Metadata-Version: 2.4
Name: laiss-docs
Version: 2.0.0
Summary: Documentos em A4 a partir de JSON. Templates que o utilizador inventa, um motor que compõe, e um servidor MCP para agentes.
Author-email: Júlio Papel <julio@laisslabs.com>
Maintainer: Laiss Labs
License: MIT
Project-URL: Homepage, https://github.com/JulioPapel/laiss-docs
Project-URL: Documentation, https://github.com/JulioPapel/laiss-docs/tree/main/docs
Project-URL: Issues, https://github.com/JulioPapel/laiss-docs/issues
Project-URL: Changelog, https://github.com/JulioPapel/laiss-docs/blob/main/CHANGELOG.md
Keywords: latex,lualatex,pdf,documentation,mcp,templates
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Documentation
Classifier: Topic :: Text Processing :: Markup :: LaTeX
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# laiss-docs

Gera documentos PDF em A4 a partir de um ficheiro JSON. O desenho é fixo — tipografia, paleta, capa e grelha iguais em todos os documentos — e o corpo é escrito em blocos JSON, nunca em LaTeX. O motor compõe o PDF e verifica-o antes de o entregar.

Este guia é para quem instalou o programa e quer produzir documentos. Não descreve como o programa é feito por dentro.

## Instalação

```bash
pip install laiss-docs
```

O programa não tem dependências Python, mas precisa de três coisas do sistema que o `pip` não instala: **LuaLaTeX**, **`pdftotext`** e **`pdfinfo`**.

A primeira compilação verifica o que falta e mostra o plano antes de mexer no sistema:

```bash
laiss-docs deps --dry-run    # o que falta, e que comandos seriam corridos
laiss-docs deps              # instala, depois de perguntar
laiss-docs deps -y           # instala sem perguntar (CI)
laiss-docs doctor            # confirma o que está pronto
```

O `deps` reconhece Debian, Ubuntu, Arch, Fedora, openSUSE, Alpine, macOS e NixOS. Em CI, a instalação automática só acontece com `LAISSDOCS_AUTO_INSTALL=1`.

## O primeiro documento

```bash
laiss-docs new relatorio --template generico --title "Relatório de Novembro"
laiss-docs build relatorio
laiss-docs preview relatorio
```

O `new` cria a pasta de trabalho com a estrutura do template. O `build` compõe e verifica. O `preview` abre o PDF.

Para escrever, abre o `doc.json` com `laiss-docs outline relatorio` para ver as secções, e usa `laiss-docs add` e `laiss-docs read` para trabalhar secção a secção. Se preferires escrever o ficheiro inteiro, o [guia de blocos](docs/blocos.md) tem todos os tipos.

## O ciclo completo

| Passo | Comando | O que faz |
|---|---|---|
| 1 | `laiss-docs templates` | Vê as formas de documento disponíveis |
| 2 | `laiss-docs new X --template Y` | Cria o documento com essa forma |
| 3 | `laiss-docs outline X` | Vê as secções e o que cada uma deve dizer |
| 4 | `laiss-docs add X "Título" --blocks b.json` | Escreve o conteúdo |
| 5 | `laiss-docs build X` | Compõe e verifica |
| 6 | `laiss-docs preview X` | Abre o PDF |
| 7 | `laiss-docs finalize X` | Guarda o PDF e apaga a pasta de trabalho |

Todos os comandos aceitam `--json`, que imprime o resultado em formato legível por máquina.

## Onde ficam as coisas

Duas pastas, com papéis diferentes:

| | Onde | O que tem |
|---|---|---|
| **Produto** | a pasta que indicaste, ex. `~/Documents/historia/` | o PDF |
| **Documento** | `~/.local/share/laiss-docs/tmp/historia/` | o `doc.json` e o `src/` |

O `doc.json` é o teu ficheiro fonte. O `src/` é LaTeX gerado, reconstruído a cada compilação, e não se edita.

Quando o documento está pronto, o `finalize` guarda o PDF em `~/Documents/laiss-docs/` com o `doc.json` ao lado (extensão `.doc.json`) e apaga a pasta de trabalho. A fonte acompanha o PDF porque sem ela o documento fecha-se para sempre: não se corrige uma gaveta, não se actualiza um número, não se muda o logótipo do cliente.

Se a pasta tiver ficheiros que o laiss-docs não criou — notas, rascunhos, um template editado à mão — o `finalize` recusa apagar e diz o que encontrou.

## Os templates

Um template é a **forma** de um documento: a ordem das secções, o que cada uma deve dizer, e o workflow de quem o escreve.

O pacote traz **um** template: o `generico`. Tem três secções — abertura, corpo e fecho — e serve qualquer documento: uma história, uma análise, uma memória, uma carta, um relatório.

Os templates especializados vivem na tua pasta pessoal (`~/.local/share/laiss-docs/templates/`) e são teus: podes editá-los, apagá-los, ou acrescentar os que quiseres. Vê os que tens com:

```bash
laiss-docs templates
```

### Escolher entre os parecidos

- **`relatorio-tecnico`** descreve um sistema que já existe e o que se mediu. **`estudo-tecnico`** responde a uma pergunta que ainda não tem resposta.
- **`proposta-comercial`** é para um cliente concreto, com preço. **`apresentacao-projecto`** é para uma reunião, com o produto e o modelo de negócio. Se há um preço a fechar, é proposta.
- **`manual-utilizador`** ensina a executar. **`runbook-operacoes`** é para executar sob pressão, quando algo falha.
- **`nota-decisao`** é o registo de uma escolha já feita. **`politica-interna`** é uma regra que se aplica a todos e é citada, não lida de seguida.

### O `generico` serve para tudo

Quando o género não é claro, começa no `generico`:

```bash
laiss-docs new relogio --template generico --title "O relógio do meu avô"
```

O `generico` não pede tabelas, números nem código. O que muda é o que tu escreves dentro. Para crescer o documento, o `expansion` do template diz o que acrescentar e quando — mais partes viram secções, uma prova é uma secção com a tabela que a mostra, passos são uma lista numerada, fontes são um anexo.

### Criar os teus templates

Duas maneiras:

```bash
laiss-docs template "Relatório de obra" --genre operacional        # do zero
laiss-docs template "Da apresentação" --from-doc ~/Documents/x.doc.json
```

O segundo copia a forma de um documento que já existe, com as secções e os metadados, e deixa o `guidance` por preencher. A partir de um documento bom, é o caminho mais rápido para repetir a estrutura.

Um template é um ficheiro `.json` em `~/.local/share/laiss-docs/templates/`, e pode ser uma pasta quando traz LaTeX próprio. A referência completa — o `guidance`, o `workflow`, a `expansion`, os blocos novos — está em **[docs/templates.md](docs/templates.md)**.

Um template do utilizador com o mesmo `id` de um do pacote **substitui-o**. O `laiss-docs templates` mostra `[utilizador]` ao lado, para se saber qual está a ganhar.

### Se apagares a pasta dos templates

Se a pasta ficar vazia, o laiss-docs repõe a base do pacote automaticamente na execução seguinte, ou explicitamente:

```bash
laiss-docs doctor --restore
```

**Nunca substitui um template teu.** Um ficheiro com o mesmo nome que já exista fica como está.

## Os temas

Um tema é a **identidade visual**: cores, tipografia, tratamento da capa.

```bash
laiss-docs themes
laiss-docs theme "Cliente ACME" --from default     # cópia editável
```

As cores são **papéis**, não valores: muda `accent` e os números de secção, os filetes e os destaques acompanham; muda `ink` e o texto muda. O tema pode trazer um logo em PDF, PNG, JPG ou SVG, e o logo viaja com o tema (o JSON e a imagem juntos).

Um tema embutido no pacote não se altera — cria-se uma cópia, para a mudança não se perder no upgrade seguinte. Como editar um tema, e o que cada campo muda, está em **[docs/temas.md](docs/temas.md)**.

## O `doc.json`

O `doc.json` tem os metadados e as secções. Um exemplo mínimo que compila:

```json
{
  "title": "Relatório de Novembro",
  "subtitle": "O que mudou no motor de compilação.",
  "language": "pt-PT",
  "sections": [
    {
      "title": "Estado actual",
      "blocks": [
        {"type": "p", "text": "O motor compila três vezes e verifica o PDF no fim. Um **parágrafo** aceita `código` e *ênfase*."},
        {"type": "h", "level": 2, "text": "O que foi feito"},
        {"type": "ul", "items": ["Blocos passaram a JSON", "Design fixo", "Cinco idiomas"]},
        {"type": "note", "title": "Uma nota", "text": "As fontes vão dentro do pacote."}
      ]
    }
  ]
}
```

Guarda-o e corre `laiss-docs new relatorio --from-json modelo.json`, seguido de `laiss-docs build relatorio`.

### Metadados

Os campos de topo mais usados: `title` (obrigatório), `subtitle`, `language`, `date` (`AAAA-MM-DD`), `classification`, `keywords`, `toc` (índice, ligado por omissão), `colophon` (página final, desligada por omissão), `abstract` (resumo) e `appendices` (anexos).

A **data** não precisa de ser escrita. Sem `date`, o documento sai com o dia em que foi compilado.

### Autores

Um autor só:

```json
{"title": "Um artigo", "coverFrom": "Ana Ribeiro", "coverFromLine": "Universidade de Exemplo"}
```

Vários autores:

```json
{
  "title": "Um artigo",
  "authors": [
    { "name": "Ana Ribeiro", "affiliation": "Universidade de Exemplo" },
    { "name": "Rui Salgado", "affiliation": "Laboratório de Exemplo" }
  ]
}
```

`authors` ganha ao `coverFrom` quando os dois estão presentes.

### Os blocos

| Tipo | Campos | Para quê |
|---|---|---|
| `p` | `text` | Um parágrafo. |
| `h` | `text`, `level` (2 ou 3) | Subtítulo dentro de uma secção. |
| `ul`, `ol` | `items` | Lista com marcas ou numerada. |
| `dl` | `items` (`term` e `def`) | Lista de definições. |
| `note`, `warn`, `rule` | `text`, `title` opcional | Caixa azul (informação), laranja (risco), cinza (norma). |
| `code`, `output` | `text`, `label` opcional | O que o leitor escreve, e o que ele vê. |
| `table` | `columns`, `rows`, `caption` opcional | Tabela com cabeçalho repetido ao passar de página. |
| `quote` | `text`, `source` opcional | Citação. |
| `pagebreak` | nenhum | Força página nova. |
| `mermaid`, `graphviz` | `source`, `caption` | Diagrama desenhado a partir de código. |
| `chart` | `labels`, `values`, `caption` | Gráfico de barras a partir de números. |
| `figure` | `path`, `caption` | Imagem que já existe. |
| `refs` | `items` (`text`, `url`, `note`) | Lista de referências. |
| `math` | `text`, `label` opcional | Fórmula em LaTeX, numerada. É o único bloco que aceita LaTeX. |

Dentro dos blocos de texto há quatro marcas: `**forte**`, `*ênfase*`, `` `código` `` e `[[caminho/ficheiro]]`. Tudo o resto é texto literal, incluindo `_`, `%` e `#`.

O `caption` das quatro famílias de figura é obrigatório: uma figura sem legenda não é referenciável no texto. A referência completa de cada bloco está em **[docs/blocos.md](docs/blocos.md)**.

## Figuras e diagramas

| Tipo | O que precisa de estar instalado |
|---|---|
| `chart` | Nada. Desenhado pelo motor a partir dos números. |
| `figure` com PNG, JPEG ou PDF | Nada. |
| `figure` com SVG | O `rsvg-convert` (pacote `librsvg2-bin` em Debian e Ubuntu). |
| `graphviz` | O `dot`, do pacote Graphviz. |
| `mermaid` | O `@mermaid-js/mermaid-cli` e um browser headless. |

O `laiss-docs deps --dry-run` diz o que falta nesta máquina, incluindo os motores de diagrama. Num cliente MCP, a ferramenta `laiss_diagrams` responde à mesma pergunta. Os caminhos das figuras são relativos à pasta do documento.

Há um guia com exemplos de cada tipo em **[docs/figuras.md](docs/figuras.md)**.

## Idiomas

```bash
laiss-docs locales
```

| Código | Idioma | Também aceita |
|---|---|---|
| `pt-PT` | Português (Portugal) | `pt`, `portugues` |
| `en-US` | English (US) | `en`, `english` |
| `es-ES` | Español (España) | `es`, `spanish` |
| `fr-FR` | Français (France) | `fr`, `french` |
| `de-DE` | Deutsch (Deutschland) | `de`, `german` |

O idioma muda a hifenização, a data por extenso, o título do índice, as etiquetas da capa e os títulos das caixas. Não muda o design.

## Quando o build falha

A mensagem diz de quem é a culpa:

```
Falhou a compilar.
  O documento não tem culpa: o problema está na máquina.

  AMBIENTE  Falta o pacote LaTeX `ltablex.sty` no sistema.
            Não é do documento: não adianta reescrever o texto.
```

| Natureza | O que é | O que fazer |
|---|---|---|
| `documento` | LaTeX escrito num bloco, um `&` fora da célula | corrigir o texto |
| `ambiente` | pacote em falta, disco cheio | resolver fora do documento |
| `template` | o `.sty` do template partido | corrigir o template |

O `build` verifica sete coisas no PDF: abre, é A4, o texto copia-se inteiro, as referências resolvem, o índice bate com as secções, não há texto encavalitado nem nada fora da mancha, e o ficheiro existe.

## Os comandos

| Comando | O que faz |
|---|---|
| `doctor` | Diz o que falta nesta máquina |
| `deps` | Instala as dependências de sistema |
| `themes` / `theme` | Lista os temas / cria um novo |
| `templates` / `template` | Lista os templates / cria um novo |
| `new` | Cria um documento |
| `build` | Compõe e verifica |
| `check` | Verifica o PDF sem recompilar |
| `finalize` | Guarda o PDF e apaga a pasta de trabalho |
| `documents` | Lista os documentos entregues |
| `preview` | Abre o PDF |
| `outline` | Lista as secções |
| `add` / `read` | Escreve e lê secções |
| `schema` | O JSON Schema do `doc.json` |
| `locales` | Os idiomas suportados |
| `init` | Instala ou actualiza fontes e estilos |
| `mcp` | Arranca o servidor MCP, para agentes AI |

Sem nome de documento, `build`, `check`, `preview`, `outline`, `add` e `read` usam o documento da pasta actual.

## Uso por agentes AI

O `laiss-docs mcp` arranca um servidor MCP sobre stdio, sem dependências. No Cursor, cria `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "laiss-docs": {
      "command": "laiss-docs",
      "args": ["mcp"]
    }
  }
}
```

O servidor expõe ferramentas para escolher ou criar temas, criar documentos, ler e editar secções e blocos, gerir autores e metadados, compilar e verificar. Um agente começa por `laiss_guide`, que devolve o processo inteiro e os erros comuns.

O laiss-docs **não tem cliente de IA**. Não pede chaves, não fala com endpoints, não sabe o que é um modelo. O modelo liga-se a ele e usa as ferramentas: assim vê o erro de validação e corrige, em vez de fazer um pedido único e devolver JSON que não cumpre o esquema.

O contrato completo está em **[docs/mcp.md](docs/mcp.md)**.

## Limites conhecidos

- **Só A4 retrato.** Outros formatos e orientação não estão previstos.
- **O corpo são blocos JSON, não Markdown livre.** A estrutura é escolhida num campo `type`; um ficheiro Markdown não se converte.
- **Sem índice remissivo nem bibliografia citável.** Há lista de referências num anexo, como texto, sem citações numeradas no corpo.
- **O design não se edita num documento.** Um aspecto diferente é um parâmetro do `doc.json` ou um tema, ou não é possível.

## Licença

MIT, Laiss Labs. As fontes mantêm as suas licenças: Inter e JetBrains Mono, OFL 1.1.
