Sintaxe do Xporter: o que funciona
Um mapa honesto de como a sintaxe de modelos no estilo Xporter é tratada quando você envia um documento do Word para o modo de modelo Word. Ele reflete o analisador de migração executado a cada envio — as mesmas classificações que você vê no relatório de compatibilidade do editor.
A promessa honesta
O Exportelier não é compatível com o Xporter, não é um substituto do Xporter e não executa modelos do Xporter. O que ele faz é ajudar você a migrar: ao enviar o documento, o analisador reconhece a sintaxe comum no estilo Xporter e informa, construção por construção, se ela já funciona, se pode ser convertida automaticamente, se precisa de reescrita manual ou se está fora de escopo por decisão de projeto.
Duas garantias firmes:
- A sintaxe de terceiros é apenas reconhecida, nunca executada. O analisador lê a forma de uma construção —
#{for …},${dateformat(…)}— e nada de um modelo enviado é avaliado como código. - Nenhum código de terceiros é copiado. Os padrões de detecção e as sugestões de apelidos foram escritos pelo Exportelier a partir de formas de sintaxe documentadas publicamente.
Cada constatação recai em uma de quatro classes.
1. Funciona sem alterações
Se o seu modelo já usa a sintaxe canônica do Exportelier, ele simplesmente funciona. Isso gera uma nota informativa, não um aviso.
| Construção | Exemplo |
|---|---|
| Token de valor | ${issue.key} |
| Laço | ${#each issue.subtasks as sub}…${/each} |
| Condição | ${#if issue.assignee}…${#else}…${/if} |
2. Convertível automaticamente
Sintaxe comum do Xporter com equivalente seguro de um para um. O editor mostra um aviso e oferece uma substituição copiável.
| Construção do Xporter | Equivalente no Exportelier | Observações |
|---|---|---|
${Key}, ${Summary}, ${Status}, … | ${issue.key}, ${issue.summary}, ${issue.status}, … | Apelidos de campos escalares. |
${Assignee.displayName} | ${issue.assignee.displayName} | Apelido de raiz conhecido; o restante do caminho é mantido. |
#{for comments} | ${#each comments as c} | Abertura de laço. |
#{if(Assignee)} | ${#if issue.assignee} | Condição simples de presença. |
#{else} | ${#else} | Marcador else. |
Apelidos escalares reconhecidos (16): Key, Summary, Description, Status, Priority, Resolution, Assignee, Reporter, Creator, Created, Updated, DueDate, IssueType, Type, Project, Labels.
Apelidos de coleção reconhecidos (5): Comments, Attachments, Subtasks, Links, Worklogs.
Uma sugestão tem a forma certa, mas o destino ainda precisa ser uma vinculação real da referência de tokens. Alguns apelidos exigem ajuste manual:
- Não vinculáveis:
Creator→issue.creator,Resolution→issue.resolution,Project→issue.project,IssueType/Type→issue.issuetype. Nenhum é vinculação de nível A. - Diferença de maiúsculas:
DueDateé sugerido comoissue.duedate; a vinculação éissue.dueDate. - Tipo incorreto:
Labelsé sugerido como escalar, masissue.labelsé uma coleção — use${#each issue.labels as l}…. - Vínculos entre itens:
Linksé sugerido comolinks, mas a vinculação real éissue.issueLinks.
3. Não suportado, mas explicável
Não há correspondência limpa de um para um, mas existe um modo claro de expressar a mesma intenção. O editor explica a reescrita; é um aviso, não um bloqueio.
| Construção do Xporter | Por quê | O que fazer em vez disso |
|---|---|---|
${Comments[0].Body} | Caminhos não aceitam indexação por colchetes. | Itere: ${#each comments as c}${c.body}${/each}. |
#{end} | Um terminador genérico. | Use o fechamento correspondente: ${/each} ou ${/if}. |
#{if(votes > 0)} | Condições testam apenas a presença de um caminho; não há operadores. | Teste a presença: ${#if issue.votes}. |
#{elseif(…)} | elseif não existe. | Aninhe as condições. |
Qualquer outra diretiva #{…} | Não reconhecida. | Substitua pela sintaxe ${…}. |
${#each}/${/if} desbalanceados, caminho incorreto, ${ não fechado | Detectado pelo analisador sintático. | Corrija o token; o relatório indica a posição exata. |
4. Inseguro ou não suportado
Fora de escopo de propósito: suportá-los transformaria o modelo em um motor de scripts, o que o Exportelier deliberadamente não é. O editor mostra um erro e a construção nunca é executada.
| Construção do Xporter | Situação | O que fazer em vez disso |
|---|---|---|
${dateformat("yyyy-MM-dd")} e outras chamadas de função ou filtro | Funções nunca são executadas. | Use o conjunto fixo de formatadores, p. ex. ${issue.created | date("yyyy-MM-dd")}. |
${jql("project = ABC")} / #{JQL: …} | JQL nunca é executado a partir de um modelo. | Escolha os itens pelo contexto de exportação. |
| JavaScript, Groovy, Velocity, FreeMarker, filtros JS | Não é uma linguagem de script. | Expresse o layout com tokens, laços, condições e formatadores. |
Variáveis set, break/continue, aritmética, expressões | Não é uma linguagem de script. | Reestruture com as construções suportadas. |
O que o validador faz com essas constatações
No envio, cada constatação vira um diagnóstico com uma severidade:
- info — funciona sem alterações, nenhuma ação necessária.
- warning — convertível automaticamente ou explicável; a exportação prossegue, mas um valor pode ficar vazio se a vinculação for desconhecida.
- error — sintaxe insegura ou não suportada, caminho inseguro ou erro de análise.
Construções que o Word preserva mas não preenche — caixas de texto, notas de rodapé, controles de conteúdo, códigos de campo, comentários e controle de alterações — são relatadas à parte como avisos unsupported-location. O documento as mantém, mas os tokens dentro delas não são preenchidos.