.md

Code blocks

Code sits on the website's dark editor surface in both themes: #202020 on the light page, #161616 on the dark one, framed by the 1.5px rule with 6px corners. Highlighting is Shiki with the dcupl theme (src/lib/shiki-dcupl-theme.ts), and <docs-code-block> renders exactly the same markup as fenced markdown.

The dcupl theme

One theme for both modes, taken from the website's terminals:

Token Color
Keywords (import, const) white, bold
Strings, numbers, true mint #b5edbd
Types and classes yellow #ffe58a
Comments gray #8f8f8f
Punctuation and operators light gray #a9a9a9
Everything else off-white #f2f2f2
import type { ModelDefinition } from '@dcupl/common';

// One theme, both modes
const productModel: ModelDefinition = {
  key: 'Product',
  properties: [
    { key: 'sku', type: 'string', index: true },
    { key: 'inStock', type: 'boolean' },
  ],
};

Basic code block

Without metadata the block has no header; the mint copy button appears on hover or keyboard focus.

const greeting = 'Hello, World!';
console.log(greeting);

With filename

Add a filename attribute for a header strip: the file name in mono semibold on a light strip (#f5f5f5, #1f1f1f in dark mode) above the rule, with the mint copy button on the right.

app.config.ts
import { ApplicationConfig } from '@angular/core';

export const appConfig: ApplicationConfig = {
  providers: [],
};

With title

Use title for a descriptive header instead of a file name:

Install dependencies
npm install @dcupl/core

Tabbed code groups

Consecutive code blocks with the same group become one panel with tabs. Tabs are mono pills with a hairline outline; the selected tab is filled with ink.

Package manager options

npm install @dcupl/core
yarn add @dcupl/core
pnpm add @dcupl/core

Framework examples

import { Component, inject } from '@angular/core';
import { DcuplService } from './dcupl.service';

@Component({
  selector: 'app-products',
  template: `<ul>
    @for (item of items(); track item.key) {
      <li>{{ item.name }}</li>
    }
  </ul>`,
})
export class ProductsComponent {
  private dcupl = inject(DcuplService);
  items = this.dcupl.query('Product');
}
import { useDcupl } from '@dcupl/react';

export function Products() {
  const { items } = useDcupl('Product');

  return (
    <ul>
      {items.map(item => (
        <li key={item.key}>{item.name}</li>
      ))}
    </ul>
  );
}
<script setup>
import { useDcupl } from '@dcupl/vue';

const { items } = useDcupl('Product');
</script>

<template>
  <ul>
    <li v-for="item in items" :key="item.key">
      {{ item.name }}
    </li>
  </ul>
</template>

Dollar patterns stay literal

Code renders exactly as written, including the String.prototype.replace patterns ($&, $1, $', $$ and the backtick form). Write samples in their natural form; there is no need to avoid them. scripts/markdown-code-blocks.spec.ts checks every code block path (plain, headers, groups, alerts, tabs, mermaid).

Replacement patterns
// Escape regex characters in user input
const escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

// Swap "Last, First" to "First Last"
const name = 'Doe, Jane'.replace(/(\w+), (\w+)/, '$2 $1');

// Text before and after the match: "key [key|value] value"
const context = 'key=value'.replace('=', " [$`|$'] ");

// A literal dollar sign in a template string
const price = `$${amount.toFixed(2)}`;

Under a model: the live preview

On a concept page, a model's code can carry a docs-model-preview underneath: a table of demo items whose columns light up together with the property lines in the code. See Data display and SDK › Models.

Usage

Filename syntax

```typescript filename="example.ts"
// Your code here
```

Title syntax

```bash title="Run the server"
npm run dev
```

Tabbed group syntax

```bash group="install" tab="npm"
npm install package
```

```bash group="install" tab="yarn"
yarn add package
```

Note: Tabbed groups need consecutive code blocks with the same group value. Any content between the blocks breaks the group.