75601988c2
- Cover, TOC, 5 dividers, 3 recap slides - 5 sections (chains, langgraph, deepagents, openswe, ecosystem) - design-system.js with theme tokens + 9 helper functions - research/: timeline + sources + per-tech notes - final-compile.js + merge.js for rebuild pipeline - output/: langchain-evolution.pptx (2.3 MB) + langchain-evolution.pdf (1.1 MB) + 7 sample previews
149 lines
8.2 KiB
Markdown
149 lines
8.2 KiB
Markdown
# design-system.md
|
||
|
||
Гайд по `lc-evo-deck/design-system.js` для тех, кто собирает слайды.
|
||
|
||
## Что внутри
|
||
|
||
`design-system.js` экспортирует единый объект с тремя слоями:
|
||
|
||
| Слой | Что лежит |
|
||
| ---------- | --------------------------------------------------------------- |
|
||
| `palette` | Цвета: фон, текст, акценты, код, состояния |
|
||
| `fonts` | `code`, `ui`, `fallback` (Arial для кириллицы) |
|
||
| `sizes` | Шкала шрифтов: `h1` ... `caption`, `eyebrow` |
|
||
| `spacing` | Отступы: `page`, `card_pad`, `gap` |
|
||
| `layouts` | Константы 16:9: `HEADER_Y`, `CONTENT_TOP`, `CONTENT_BOTTOM`, `FOOTER_Y` |
|
||
| `theme` | Все перечисленное выше в одном объекте (удобно пробрасывать) |
|
||
| `helpers` | Готовые функции для сборки слайда |
|
||
|
||
Импорт:
|
||
|
||
```js
|
||
const ds = require('./design-system');
|
||
const { theme, helpers, layouts } = ds;
|
||
```
|
||
|
||
## Геометрия слайда (16:9, дюймы)
|
||
|
||
```
|
||
y=0.00 +-----------------------------------------------+
|
||
| HEADER_Y = 0.4 |
|
||
| eyebrow (10pt, accent) |
|
||
y=1.25 | --- hairline --- |
|
||
| CONTENT_TOP = 1.4 <-- начинай контент тут |
|
||
| |
|
||
| контент |
|
||
| |
|
||
y=5.05 | CONTENT_BOTTOM = 5.05 |
|
||
| FOOTER_Y = 5.25 <-- page number, source |
|
||
y=5.625 +-----------------------------------------------+
|
||
x=0.5 x=9.5
|
||
^ отступ `spacing.page` (0.5 дюйма) с обеих сторон
|
||
```
|
||
|
||
## Минимальный слайд
|
||
|
||
```js
|
||
const pptxgen = require('pptxgenjs');
|
||
const ds = require('./design-system');
|
||
const { theme, helpers, layouts } = ds;
|
||
|
||
const pres = new pptxgen();
|
||
pres.layout = 'LAYOUT_16x9';
|
||
|
||
const slide = pres.addSlide();
|
||
helpers.slideBase(slide, pres, theme);
|
||
helpers.addHeader(slide, pres, theme, {
|
||
section: 'Stage 2: Chains',
|
||
sectionNumber: 2,
|
||
title: 'LCEL: composable expressions',
|
||
eyebrow: 'STAGE 2',
|
||
});
|
||
helpers.addPageNumber(slide, pres, theme, 1);
|
||
|
||
await pres.writeFile({ fileName: 'lc-evolution.pptx' });
|
||
```
|
||
|
||
## Какой layout для какого случая
|
||
|
||
| Слайд | Что использовать |
|
||
| ------------------------------ | --------------------------------------------------------- |
|
||
| Титул раздела / stage divider | `helpers.addSectionDivider` (большая цифра + заголовок) |
|
||
| Текст + код | `addHeader` + `addCodeBlock` слева, `addCallout` справа |
|
||
| Сравнение двух подходов | `addProsCons` (две колонки, + и -) |
|
||
| Цитата / важное замечание | `addCallout` с `kind: 'info' | 'warning' | 'success' | 'danger'` |
|
||
| Код с акцентом на строке | `addCodeBlockWithHighlight` + `lines: [3, 4]` |
|
||
| Источник внизу | `addSourceLine` |
|
||
| Любой слайд | `addPageNumber` в правом нижнем углу |
|
||
|
||
## Helper-функции -- короткая справка
|
||
|
||
### `slideBase(slide, pres, theme)`
|
||
Закрашивает фон `bg.primary`. Вызывай первым на каждом слайде.
|
||
|
||
### `addHeader(slide, pres, theme, opts)`
|
||
- `opts.eyebrow` -- маленький caps-ярлык сверху (например `STAGE 2: CHAINS`)
|
||
- `opts.section` -- альтернатива eyebrow
|
||
- `opts.sectionNumber` -- крупная цифра справа (необязательно)
|
||
- `opts.title` -- h1
|
||
|
||
### `addCodeBlock(slide, pres, theme, opts)`
|
||
- `opts.code` -- строка кода (`\n` для переносов)
|
||
- `opts.filePath` + `opts.startLine` -- подпись `// path/to/file.py:1-12`
|
||
- `opts.highlightLines` -- массив 1-based номеров строк, которые подсветить
|
||
- Если строк больше, чем влезает по высоте, внизу появится желтая плашка
|
||
`// note: snippet has N lines, card fits ~M` -- уменьши `fontSize` или
|
||
разбей сниппет.
|
||
|
||
### `addCodeBlockWithHighlight(slide, pres, theme, opts)`
|
||
То же самое, но принимает `lines: [3, 4]` как алиас для `highlightLines`.
|
||
|
||
### `addCallout(slide, pres, theme, opts)`
|
||
- `opts.kind` -- `info` | `warning` | `success` | `danger`
|
||
- `opts.title` -- необязательный заголовок внутри плашки
|
||
- `opts.text` -- основной текст
|
||
|
||
### `addProsCons(slide, pres, theme, opts)`
|
||
- `opts.pros` -- массив строк
|
||
- `opts.cons` -- массив строк
|
||
- Плюсы слева (зелёная рамка), минусы справа (красная).
|
||
|
||
### `addPageNumber(slide, pres, theme, n)`
|
||
Правый нижний угол, монохромный caption.
|
||
|
||
### `addSectionDivider(slide, pres, theme, opts)`
|
||
- `opts.number` -- крупная цифра слева
|
||
- `opts.title` -- заголовок справа
|
||
- `opts.eyebrow` -- необязательный caps-ярлык
|
||
- `opts.intro` -- абзац под заголовком
|
||
|
||
### `addSourceLine(slide, pres, theme, opts)`
|
||
- `opts.source` -- URL или короткая ссылка
|
||
- По умолчанию `x=0.5, y=5.30, w=7.0`
|
||
|
||
### `highlightPython(code)` (опционально)
|
||
Если на машине стоит `pygmentize` (из пакета `pygments`), функция вернет
|
||
массив `{ text, color }` токенов. Если бинарника нет -- вернется один токен
|
||
с дефолтным цветом и весь код отрисуется моноширинно. Используй, когда
|
||
нужна попроцедурная подсветка поверх `addCodeBlock`.
|
||
|
||
## Правила
|
||
|
||
1. Не вставляй em-dash (`--`) и en-dash (`-`) -- заменяй на `--` и `-`.
|
||
2. Не используй Unicode-кавычки -- только ASCII `"` и `'`.
|
||
3. Не используй `...` -- заменяй на `...`.
|
||
4. Шрифты -- всегда через `helpers.withFallback(name)`, чтобы Arial был
|
||
гарантированным фолбэком.
|
||
5. Цвета бери из `palette.*` -- не хардкодь hex в слайдах.
|
||
6. Геометрия -- через `layouts.*` константы.
|
||
7. Любой новый слайд начинается с `slideBase(...)`.
|
||
|
||
## Частые ошибки
|
||
|
||
| Симптом | Причина | Фикс |
|
||
| -------------------------------------- | ------------------------------------ | --------------------------------------------------- |
|
||
| Шрифт Arial вместо JetBrains Mono | PowerPoint не нашел шрифт | Установи `JetBrains Mono` в систему |
|
||
| Кириллица в коде рендерится квадратами | Нет фолбэка | Используй `helpers.withFallback(t.fonts.code)` |
|
||
| Код вылезает за карточку | Слишком много строк | Уменьши `sizes.code` или укороти сниппет |
|
||
| Header и контент перекрываются | Контент начинается выше `CONTENT_TOP`| Подними `y` до `layouts.CONTENT_TOP` |
|
||
| Плашка `note: snippet has N lines` | Сниппет не помещается | Разбей на 2 карточки или уменьши `sizes.code` | |