Онлайн-авторинг (Writespace)
В этом руководстве описан встроенный модуль онлайн-авторинга Papex (точка входа /writespace) — браузерное письменное место, не требующее локальной установки TeX и рукописного JSON. Он переносит поток «загрузка исходного пакета» из Руководства по подаче прямо в браузер: вы заполняете метаданные и пишете тело онлайн, а система генерирует корректный papex.json и файлы разделов .tex. Затем вы можете экспортировать tar.gz или опубликовать на платформе в один клик.
1. Обзор
1.1 Какие проблемы он решает
| Проблема классической «загрузки исходного пакета» | Что делает онлайн-авторинг |
|---|---|
Рукописный papex.json подвержен ошибкам (пропущенные поля, плохой формат) | Визуальный редактор + проверка в реальном времени |
| Проверка структуры требует локальной установки Python / TeX | Промежуточный .tex генерируется в браузере — без локального инструментария |
| Упаковка и загрузка — два отдельных шага | «Экспорт» и «Публикация» одним кликом из редактора |
| Потеря работы в процессе черновика | Автосохранение в localStorage браузера |
1.2 Три вкладки
| Вкладка | Назначение |
|---|---|
| Метаданные | Информация о работе, авторы, ссылки, параметры сборки — визуальный редактор для papex.json |
| Тело | Структурированная рабочая зона разделов / приложений для написания тела на LaTeX |
| Экспорт и публикация | Проверка в реальном времени, предпросмотр файлов архива, экспорт tar.gz / публикация в один клик |
1.3 Связь с системой подачи
Онлайн-авторинг — это не новый способ подачи, а интерфейс авторинга «загрузки исходного пакета». Создаваемый им архив побайтово совместим с загрузкой исходного пакета, а публикация повторно использует ту же серверную конечную точку POST /api/submit/archive, следуя тому же конвейеру «распаковка → проверка → создание работы → связывание графа цитирований → сборка PDF» (см. Руководство по подаче §4).
2. Точка входа и права доступа
- Точка входа:
/writespace. - Аутентификация на уровне страницы: серверный компонент
src/app/writespace/page.tsxвызываетgetCurrentUser()иredirect("/login")при отсутствии аутентификации. - Промежуточный слой:
src/middleware.tsдобавляет/writespaceвPROTECTED_PREFIXESи добавляет/writespace/:path*вmatcher, поэтому неаутентифицированные запросы блокируются на границе. - Право публикации: публикация по сути является подачей исходного пакета и подчиняется тем же правилам
FORBIDDEN/PAPER_NOT_FOUNDв Руководстве по подаче §4 — когдаpaper.idобъявляет новую версию, вы должны иметь право подачи для этой работы.
3. Вкладка первая: редактор метаданных
Вкладка Метаданные соответствует MetadataEditor. Она разбивает блоки paper / authors / references / build из papex.json на карточные формы с полями, сопоставленными один-к-одному с Руководством по подаче §3.2.
3.1 Информация о работе (metaPaper)
Название, подзаголовок, аннотация, ключевые слова (через запятую), основная категория (выпадающий список, обязательно), дополнительные категории (добавить/удалить), DOI, лицензия (выпадающий список, по умолчанию CC-BY-4.0), место публикации (venue), примечание к версии, язык, ID работы (необязательно — если заполнен и принадлежит одной из ваших существующих работ, подаётся как новая версия).
3.2 Авторы (metaAuthors)
- Добавьте нескольких авторов; каждая карточка поддерживает перемещение вверх/вниз/удаление.
- Поля: имя (обязательно), аффилиация, email, ORCID (проверка формата), домашняя страница, переключатель ответственного автора, переключатель равного вклада, сноска, порядок.
- Ответственный автор / равный вклад / сноска отображаются как сноски
\thanksв PDF; ORCID и домашняя страница также появляются в сносках.
3.3 Ссылки (metaReferences)
- Добавьте несколько записей BibTeX; поля включают ключ цитирования (обязательно, проверка формата), тип (выпадающий список, 12 типов BibTeX), название, автор, журнал, booktitle, год, DOI, URL, arXiv ID, страницы, том, номер, издатель, примечание.
- Две цели: ① при публикации связываются в граф цитирований платформы через
mapReferencesToCitations; ② при экспорте используются для автогенерацииreferences.bib(см. §7).
3.4 Параметры сборки (metaBuild)
- Стиль библиографии:
numeric/authoryear(внедряется в основной документ как\documentclass[11pt,bibstyle=authoryear]). - Колонки:
1/2(две колонки внедряютtwocolumn). - Прочие параметры
build(напр.fontset,documentclass) зарезервированы для серверной компиляции; значения по умолчанию см. вcreateDefaultDraft.
3.5 Проверка в реальном времени
Каждое изменение проходит через validateDraft() (src/lib/writespace/manifest.ts); результат передаётся вкладке Экспорт и публикация. Основные правила:
| Проверка | Правило | Тип |
|---|---|---|
schemaVersion | должно совпадать с x.y.z | ошибка |
paper.title / abstract / primaryCategoryId | обязательны и непусты | ошибка |
paper.id (необязательно) | если присутствует, должно совпадать с YYMM.NNNNN | ошибка |
authors | минимум 1; у каждого name обязательно; orcid должен совпадать с 0000-0000-0000-0000 | ошибка |
sections | минимум 1; у каждого file обязательно; id только буквы, цифры, -, _ | ошибка |
references | у каждого key обязательно, ограничено A-Za-z0-9_:+.-; year ∈ [0, 3000] | ошибка |
| пустое тело раздела | рекомендация | предупреждение |
«ошибки» блокируют публикацию; «предупреждения» (напр. пустое тело раздела) носят лишь рекомендательный характер.
4. Вкладка вторая: рабочая зона тела
Вкладка Тело соответствует SectionsEditor и управляет структурно телом работы и приложениями.
4.1 Список разделов
- Каждый раздел (или приложение) — сворачиваемая карточка с: id/именем файла (
file, напр.sections/intro.tex), названием раздела, уровнем (section/subsection/subsubsection/chapter/part), телом (поле LaTeX), счётчиком символов. - Поддерживает: добавить раздел, добавить приложение, переместить вверх/вниз, удалить.
- Уровень определяет команду, выдаваемую при экспорте (
\section{Title}→\input{sections/intro.tex}).
4.2 Правила содержимого тела
- Файл раздела
.texпишется вручную и поддерживает полный LaTeX: математику, рисунки, свои команды, и ссылки\cite{key}(соответствующие ключам ссылок). - Тело раздела не экранируется (в соответствии с Руководством по подаче §3.3); только текстовые поля в «Метаданных» экранируются.
- Кнопка «Вставить примеры разделов» записывает пять демонстрационных разделов (введение / связанные работы / метод / эксперименты / заключение) с LaTeX-формулами для быстрого старта.
4.3 Приложения
Записи приложений используют структуру разделов и выдаются после одиночного \appendix.
5. Вкладка третья: Экспорт и публикация
Вкладка Экспорт и публикация соответствует ExportPanel — выходу из всего потока.
5.1 Состояние проверки
Показывает результат validateDraft() в реальном времени сверху: «допустимо» или «недопустимо» плюс список ошибок/предупреждений. Кнопка Публикация отключена, пока есть ошибки.
5.2 Предпросмотр манифеста файлов
Показывает файлы архива, которые будут созданы (т. е. вывод buildArchiveFiles, §7), чтобы вы могли подтвердить структуру перед загрузкой/публикацией.
5.3 Экспорт tar.gz
Нажмите Экспорт: tar.gz генерируется целиком в браузере и запускает загрузку (имя файла из i18n writespace.expDownloadName).
- Полностью без зависимостей:
src/lib/writespace/targz.tsвручную реализует упаковку POSIX ustar плюс нативныйCompressionStream('gzip')— без участия сервера. - Шаблонные ресурсы (
papex-template.tex/papex.cls) извлекаются в момент экспорта из/writespace/papex-template.texи/writespace/papex.clsи включаются в архив, сохраняя его самодостаточным (серверная часть компилирует напрямую черезlatexmk).
5.4 Публикация в один клик
Нажмите Публикация: выполняет те же шаги генерации, что и экспорт, затем POST-ит tar.gz как поле file запроса multipart/form-data на /api/submit/archive.
- Для публикации требуется
validation.valid === trueзаранее. - При успехе показывает возвращённые «ID работы + версию» и
warningsсо ссылкой «открыть работу» и сбрасывает локальный флаг черновика. - При ошибке показывает сообщение об ошибке сервера прямо в интерфейсе (сопоставление в таблице ошибок Руководства по подаче §4).
6. Автосохранение и восстановление черновика
- Черновик (
manifest+ тело каждого раздела) автосохраняется вlocalStorageбраузера (ключ:papex-writespace-draft), с дебаунсом 400 мс — переживает закрытие страницы. - Повторное открытие
/writespaceавтоматически восстанавливает последний черновик и показывает «локальный черновик восстановлен»; после редактирования показывает «автосохранено». - Верхняя кнопка Новый запрашивает подтверждение, очищает
localStorageи сбрасывает в пустой черновик (с одним примером вводного раздела).
Черновики живут только в локальном браузере; смена устройства или очистка данных браузера теряет их. Для важной работы помните об Экспорте или Публикации.
7. Структура экспортируемого архива
tar.gz, создаваемый Экспортом / Публикацией, собирается buildArchiveFiles() и полностью совместим с тем, что ожидает серверный papex-archive.ts:
my-paper.tar.gz
├── papex.json # манифест редактора, сериализован (отступ 2 пробела)
├── papex-template.tex # основной документ с внедрёнными bibstyle/twocolumn
├── papex.cls # класс документа (взят из /writespace/papex.cls)
├── references.bib # автогенерируется из ссылок (опускается, если их нет)
├── sections/
│ ├── intro.tex # раздел, написанный вами в «Теле»
│ └── …
└── _papex_*.tex # автогенерируемые промежуточные фрагменты (не редактировать)
├── _papex_meta.tex # название/авторы/аффилиации/ключевые слова/бегущий заголовок
├── _papex_abstract.tex # аннотация
├── _papex_sections.tex # сборка \section + \input
├── _papex_backmatter.tex # благодарности/финансирование
└── _papex_appendices.tex # \appendix + приложения- Файлы
_papex_*.texсоздаютсяgenMeta/genAbstract/genSections/genBackmatter/genAppendices; текстовые поля проходят однопроходноеlatexEscape, а тела разделов —\inputдословно. - Этот архив можно загрузить вручную на странице «загрузка исходного пакета» или отправить автоматически кнопкой Публикация — они эквивалентны.
8. Заметки по реализации
| Задача | Реализация |
|---|---|
| Модель данных | src/lib/writespace/manifest.ts: типы, согласованные с papex.schema.json + papex-json.ts, чистый фронтенд, без серверных импортов |
| Генерация LaTeX | src/lib/writespace/latex-gen.ts: перенос логики papex-build.py на TS; экранирование использует однопроходное сканирование символов (согласованно с фиксированным papex-build.py, избегая повторного экранирования \textbackslash{}) |
| Упаковка | src/lib/writespace/targz.ts: ручной ustar + CompressionStream('gzip'), без зависимостей, чистый браузер |
| Шаблонные ресурсы | public/writespace/papex.cls + papex-template.tex (скопированы из papex-latex/, с нормализацией LF), извлекаются во время выполнения в архив |
| Оркестрация | src/components/writespace/writespace-client.tsx: три Tabs + сохранение черновика + экспорт/публикация |
| Интернационализация | src/i18n/dictionaries/{zh,en}.ts блок writespace (~70 ключей), соответствует меткам UI |
9. Безопасность и ограничения
- Права доступа: и вход, и публикация требуют входа; целевая работа новой версии должна принадлежать текущему пользователю (или привилегированной роли), иначе сервер возвращает
FORBIDDEN. - Без серверного сохранения: вся генерация и упаковка происходят в памяти браузера; файлы покидают машину только когда вы нажимаете загрузку/публикацию. Платформа всё равно применяет TeX-песочницу, ограничения размера и отключение shell-escape из Руководства по подаче §6/§7.
- Поддержка браузеров:
CompressionStream('gzip')требует свежего браузера (Chrome/Edge 80+, Firefox 113+, Safari 16.4+); при отсутствии экспорт завершается дружелюбным сообщением. - Лимит 50 МБ: публикация проходит через
/api/submit/archiveи подчиняется тому же лимиту 50 МБ.
10. Часто задаваемые вопросы
В: Онлайн-авторинг или загрузка исходного пакета — что выбрать? Любое. Онлайн-авторинг подходит авторам, которые не хотят командную строку и хотят живую проверку; загрузка исходного пакета подходит тем, у кого есть локальный проект TeX и нужен тонкий контроль papex-build.py. Оба дают идентичный результат в базе данных.
В: Можно ли экспортированный tar.gz загрузить вручную на странице «загрузка исходного пакета»? Да, и это эквивалентно. Экспортированный архив уже включает papex.cls и papex-template.tex, поэтому серверу не нужно копировать их из PAPEX_LATEX_DIR.
В: Я использовал \cite{key} в теле, но ссылка не связалась после публикации? Связывание ссылок зависит от того, совпадают ли doi / arxivId ссылки с работой, уже находящейся на платформе; записи только с url / title попадают в граф цитирований, но не формируют внутреннюю ссылку. Проверьте точность DOI / arXiv ID ссылки.
В: Синхронизируются ли черновики в облако? Нет. Черновики живут только в localStorage браузера; смена устройства или очистка кэша теряет их. Привыкайте делать Экспорт или Публикацию.
В: Не исказятся ли формулы $...$ в теле? Нет. Файл раздела .tex записывается дословно (без экранирования); формулы рендерятся серверной компиляцией XeLaTeX. Только текстовые поля в «Метаданных» экранируются.
В: Нет PDF сразу после публикации? То же, что в ЧаВО Руководства по подаче: зависит от того, настроен ли на сервере TeX Live; если нет, pdfUrl пуст, и страница показывает «PDF собирается в фоне».