# cssyntax – syntax layer for structured command names

`cssyntax` (short for Control Sequence Syntax) is a standalone LaTeX2e package that provides a readable, self-documenting syntax for internal command names. By temporarily turning the punctuation characters _ , : and / into letters, it lets package authors write descriptive, hierarchically structured names that make the intent of the code clear at a glance – even years after it was written.

```latex
\container_module_type_sub-type/description
```

Alongside this naming layer, cssyntax offers a small set of readable aliases for common TeX primitives, built around the `\_fun_ ` prefix and the two separators / and :. Originally developed as the core of the lingwrit bundle, it is now a general‑purpose tool for any author seeking to keep their internal API maintainable and self-explanatory.

## Motivation

Traditional LaTeX command names are flat and cryptic: `\@firstoftwo`,
`\expandafter`, `\g@addto@macro`, etc.
`cssyntax` opens a naming space where intent is immediately readable
without sacrificing robustness: the commands remain ordinary TeX
control sequences, simply written with extended letter-category
characters.

---

## Installation

Place `cssyntax.sty` in a directory visible to your TeX distribution.
No special compilation is needed. Load the package in the preamble:

```latex
\usepackage{cssyntax}
```

The package activates the extended syntax automatically **after**
defining its own bootstrap commands. Thus the remainder of your file
can immediately use structured names.

---

## Dependencies

- `xifthen`
- `xparse`
- `expl3`
- `l3keys2e`

These packages are loaded by `cssyntax` before the syntax is
activated, so the `\RequirePackage` calls still use standard catcodes.

---

## Activation / Deactivation

- `\csSyntaxOn` (or its synonym `\csSyntaxEnabled`)
  Activates `_`, `:` and `/` as letters (catcode 11). Opens a scope
  in which structured names can be typed directly.

- `\csSyntaxOff` (or `\csSyntaxDisabled`)
  Restores the original catcodes: `_` → 8, `:` → 12, `/` → 12.
  Any call to a command containing these characters must occur
  **before** this deactivation.

The idea is to write the “implementation” part of your module between
`\csSyntaxOn` and `\csSyntaxOff`, or to leave the syntax globally
active if you are the only one writing internal code.

---

## Naming conventions

The provided commands follow a regular hierarchy:

- **`\_fun_`** : root prefix (internal function / operation).
- **First segment after `_fun_`** : domain or action (`copy`,
  `define`, `expand`, `build`, `save`, `use`, `swap`, `pick`,
  `gobble`, `load`, `enter`, `exit`, `declare`).
- **`/` separator** : sub-type or description (e.g. `cs`, `exp`,
  `group`, `first`, `if_exists`).
- **`:` synonym** : for every `/` command, a `:` alias is
  automatically created using `\NewCommandCopy`. Example:
  `\_fun_copy/cs` and `\_fun_copy:cs` are identical.

This convention makes commands easy to memorise and discover, while
remaining compatible with TeX’s parsing (underscore and colon are
letters within the active scope).

---

## Provided commands

### Definition and copying

| Command | Role |
|---------|------|
| `\_fun_copy/cs{<target>}{<source>}` | Raw `\let` (overwrites without protection) |
| `\_fun_define/cs <cs> {<text>}` | `\def` |
| `\_fun_define/exp <cs> {<text>}` | `\edef` (local expansion) |
| `\_fun_define/global <cs> {<text>}` | `\gdef` |
| `\_fun_define/global_exp <cs> {<text>}` | `\xdef` |
| `\_fun_define/protected_exp <cs> {<text>}` | `\protected@edef` |

### Expansion and introspection

| Command | Role |
|---------|------|
| `\_fun_expand/after` | `\expandafter` |
| `\_fun_expand/prevent` | `\noexpand` |
| `\_fun_build/cs{<name>}` | `\csname...\endcsname` (creates `\relax` if unknown) |
| `\_fun_build/def{<name>}<params>{<body>}` | `\cs_new:cpn` (refuses to redefine) |
| `\_fun_build/redef{<name>}<params>{<body>}` | `\cs_set:cpn` (always overwrites) |
| `\_fun_get/cs_string <cs>` | `\string` |
| `\_fun_get/cs_meaning <cs>` | `\meaning` |

### Groups

| Command | Role |
|---------|------|
| `\_fun_enter/group` / `\_fun_exit/group` | `\begingroup` / `\endgroup` (general scope) |
| `\_fun_enter/token_group` / `\_fun_exit/token_group` | `\bgroup` / `\egroup` (explicit group tokens) |

### Saving, using, resetting, swapping

| Command | Role |
|---------|------|
| `\_fun_save/cs{<name>}` | Stores the current definition |
| `\_fun_use/cs{<name>}` | Recalls the saved definition |
| `\_fun_reset/cs{<name>}` | Resets `<name>` to `\relax` |
| `\_fun_swap/cs{<cs1>}{<cs2>}` | Exchanges the definitions of two CS |

### Selection and gobbling

| Command | Role |
|---------|------|
| `\_fun_pick/first{<a>}{<b>}` | Keeps `<a>` (`\@firstoftwo`) |
| `\_fun_pick/second{<a>}{<b>}` | Keeps `<b>` (`\@secondoftwo`) |
| `\_fun_gobble/one{<arg>}` | Absorbs one argument (`\@gobble`) |
| `\_fun_gobble/two{<a>}{<b>}` | Absorbs two arguments (`\@gobbletwo`) |

### File loading

| Command | Role |
|---------|------|
| `\_fun_load/{<file>}` | `\input` |
| `\_fun_load/if_exists{<file>}{<if found>}{<if not found>}` | `\IfFileExists` + `\input` |
| `\_fun_enter/source` | Visual marker (no-op) for the top of a loaded file |
| `\_fun_exit/source` | `\endinput` (stops reading the current file) |

### Low‑level environment declaration

- **`\_fun_declare/env{<name>}{<enter code>}{<exit code>}`**
  Creates `\_fun_enter/<name>`, `\_fun_exit/<name>`, and
  `\_fun_use/<name>{<content>}` (plus their `:` synonyms).
  No automatic grouping; you must place `\begingroup`/`\bgroup`
  yourself in the enter/exit code if needed.

- **`\_fun_declare/auto_group{<name>}{<enter code>}{<exit code>}`**
  Same as above, but automatically wraps the enter code in
  `\begingroup` and the exit code in `\endgroup`.

### Booleans

| Command | Role |
|---------|------|
| `\_fun_declare/bool{<name>}` | Creates a boolean (via `\newboolean` of `xifthen`), prefixed by `_user_bool/` |
| `\_fun_set_true/bool{<name>}` | `\setboolean{_user_bool/<name>}{true}` |
| `\_fun_set_false/bool{<name>}` | `\setboolean{_user_bool/<name>}{false}` |
| `\_fun_enter/test_bool{<name>}` | `\boolean{_user_bool/<name>}` (usable in an `\ifthenelse` test) |
| `\_fun_exit/test_bool` | `\relax` (visual closing) |

---

## Usage notes

1. **Syntax scope**
   Any command containing `/` must be invoked while `\csSyntaxOn` is
   active. If you call `\csSyntaxOff` too early, `/` reverts to an
   “other” character and the name will be split into multiple tokens.

2. **`:` aliases**
   The `\...:...` synonyms are created with `\NewCommandCopy`; they
   are safe against accidental redefinitions. The internal primitives
   like `\_fun_copy/cs`, however, use raw `\def` or `\let` to remain
   idempotent and reusable.

3. **`\_fun_build/def` and `\_fun_build/redef`**
   The `<params>` argument must be passed exactly as
   `\cs_new:cpn{<name>}` would expect it. Do not add extra braces
   around the parameters in the calling code.

4. **Declared environments**
   `\_fun_use/<name>{<content>}` opens the environment, inserts the
   content, then closes it. It can be used in the preamble as well as
   in the document body.

5. **Booleans**
   Booleans are stored under the internal prefix `_user_bool/` to
   avoid collisions. You can still choose a descriptive name for the
   boolean (e.g. `nx_note_forced_margin`).

---

## Licence

`cssyntax` is part of the `lingwrit` suite. The exact licence is not
yet fixed in this version; for now, consider it freely usable for
testing purposes.

---

## History

- **2026/07/20 v0.1.0** – Initial documented version.
