Disclaimer Tradução e adaptação do manual produzido por D. Richard Hipp. O texto original pode ser acessado no projeto pikchr.

Introdução

Este é um guia para gerar diagramas usando o Pikchr (pronuncia-se "picture"). Este guia é projetado para ensiná-lo a usar o Pikchr. Não é uma referência para o Linguagem Pikchr (que é um documento separado), nem é uma explicação de por que você pode querer usar o Pikchr. O objetivo aqui é fornecer um tutorial prático e acessível sobre o uso do Pikchr.

Execução de scripts Pikchr

O objetivo do design do Pikchr é permitir diagramas de linhas incorporados no Markdown ou outras linguagens. Para o propósito deste tutorial, escreveremos apenas scripts Pikchr puros sem a marcação ao redor. Para experimentar com Pikchr, visite nosso aplicativo Pikup. Digite o seguinte script

line; box "Olá" "mundo!"; arrow

Se você fizer isso direito, a saída deve aparecer como:

Olá mundo!

Então vamos lá: você criou e renderizou seu primeiro diagrama usando Pikchr! Você fará bem em manter o Pikup à mão, em um janela separada do navegador, para que você possa experimentar os scripts à medida que avança através deste tutorial.

Sobre os scripts Pikchr

O Pikchr foi projetado para ser simples. Um script Pikchr é apenas uma sequência de instruções Pikchr, separadas por novas linhas ou ponto e vírgula. O exemplo "Olá mundo!" acima usou três declarações, uma "linha" (line), uma "caixa" (box) e uma "seta" (arrow), cada uma separada por ponto e vírgula.

Espaço em branco (exceto novas linhas) e comentários são ignorados. Comentários em pikchr podem estar no estilo de TCL, C ou C++. Ou seja, comentários consistem em um "#" ou "//" e inclue todos os caracteres até o final da linha. Além disso, todo o texto entre "/*" e "*/" tábem é um comentário. O script do exemplo acima pode ser reescrito com cada instrução em uma linha separada e com comentários descrevendo o que cada declaração é fazendo:

# O primeiro componente é uma linha
line
// O segundo é uma caixa com o texto "Olá, mundo!"
box "Olá," "mundo"
/* Finalmente uma seta */
arrow
Olá, mundo!

Lembre-se de que novas linhas separam instruções. Se você tiver uma declaração longa que precisa ser dividido em várias linhas, acrescente um caractere de barra invertida no final da linha e a nova linha será tratados como qualquer outro espaço:

line
box \ 
  "Olá," \ 
  "Mundo!"
arrow

Portanto, um script Pikchr é apenas uma lista de declarações, mas o que é uma declaração?

Declarações do Pikchr

A maioria das declarações são descrições de um único objeto gráfico que torna-se parte do diagrama. O primeiro token da instrução é o nome da classe do objeto. As seguintes classes são atualmente suportadas:

box circle ellipse oval cylinder file line arrow spline dot arc text

Uma instrução pode ser apenas o nome da classe e nada mais, mas o nome da classe geralmente é seguido por um ou mais "atributos". Os atributos são usados para modificar a aparência do objeto, ou para posicionar o objeto relativo a objetos anteriores.

Então, para revisitar o script de demonstração "Olá, Mundo!" acima, vemos que esse script contém três descrições de objeto:

  1. Um objeto de line sem atributos (o que significa que a linha é mostrada sem alterações em sua aparência padrão).
  2. Um objeto box com dois atributos literais de texto. A sequênciq de atributos literais fazem com que os textos correspondentes sejam desenhadas dentro da caixa.
  3. Um objeto arrow sem atributos.

Layout

Por padrão, os objetos são empilhados um ao lado do outro da esquerda para a direita. O mecanismo de layout do Pikchr acompanha a "direção do layout", que pode ser "direita", "para baixo", "esquerda" ou "para cima". A direção do layout padrão é "direita", mas você pode alterá-lo usando uma declaração que consiste apenas no nome da nova direção. Então, se inserirmos a instrução down na frente do nosso script de teste, como esse:

down
line
box  "Olá,"  "mundo!"
arrow

Em seguida, os objetos são empilhados movendo-se para baixo:

Olá, mundo!

Ou você pode alterar a direção do layout para esquerda:

Olá, mundo!

Ou para "subir":

Olá, mundo!

É comum empilhar objetos de linha (linhas, setas, splines) contra objetos de bloco (caixas, círculos, elipses, etc.), mas isso não é necessário. Você pode empilhar vários objetos de bloco juntos. Por exemplo:

box; circle;  cylinder

Resultado:

Mais frequentemente, você deseja colocar espaço entre os objetos de bloco. O objeto especial move existe para esse propósito. Considere:

box; move; circle; move; cylinder

Este script cria os mesmos três objetos de bloco, mas com espaço em branco entre eles:

Nota: Um "movimento" é realmente apenas uma "linha" invisível. Então o script a seguir gera a mesma saída que o anterior.

box; line invisible; circle; line invisible; cylinder

Controle de layout usando atributos

O empilhamento automático de objetos é conveniente em muitos casos, mas a maioria dos diagramas vai necessitar de alguns objetos colocados em algum lugar diferente do que imediatamente adjacente ao seu antecessor. Por isso, a disposição são fornecidos atributos que permitem a colocação precisa de objetos.

Para ver como isso funciona, considere o exemplo anterior de uma caixa, círculo, e cilindro separados por algum espaço. Suponha que queremos desenhar uma seta que desce para fora da caixa, depois para a direita, depois para cima na cilindro. O script completo pode ser mais ou menos assim:

box; move; circle; move; cylinder
arrow from first box.s \ 
  down 1cm \ 
  then right until even with first cylinder \ 
  then to first cylinder.s

Esse script resulta no seguinte diagrama:

Essa é realmente a imagem que queremos, mas há muitas palavras em naquela declaração de arrow! Não entre em pânico. É bem simples. Vamos quebrá-la em partes e explicá-la peça por peça.

Primeiro observe que a instrução arrow é dividida em quatro linhas de texto, com um \ no final das três primeiras linhas para impedir que a nova linha subsequente feche prematuramente a instrução. Dividir a arrow em linhas separadas dessa maneira é puramente para legibilidade humana. Se você se sentir mais confortável colocando todo o declaração em uma linha, tudo bem também. O Pikchr não se importa. Apenas certifique-se de lembrar das barras invertidas se você dividir linhas!

Os atributos na instrução arrow descrevem o caminho percorrido por a flecha. O primeiro atributo é from first box.s. Este from é o atributo que especifica onde a seta começa. Neste caso, começa no ponto de ancoragem "s" (ou "sul") da "primeira caixa". A "primeira caixa" parte é provavelmente auto-explicativa. (Você também pode escrever como 1st box em vez de "primeira caixa" e, de fato, o legacy-PIC requer o uso de 1st em vez de first.) Mas o que é a parte ".s"?

Cada objeto de bloco tem oito pontos de ancoragem em seu perímetro que são nomeados para pontos cardeais, assim:

.nw  .w  .sw  .s  .se  .e  .ne .n  .c .nw  .w  .sw  .s  .se  .e  .ne .n  .c .nw  .w  .sw  .s  .se  .e  .ne .n  .c

Como você pode ver, há também um nono ponto no meio chamado ".c". Cada objeto de bloco tem esses pontos de ancoragem; você pode se referir a eles ao posicionar o próprio objeto ou ao posicionar outros objetos em relação ao objeto de bloco. Neste caso, estamos iniciando o seta na âncora ".s" da caixa.

A próxima frase na instrução arrow é down 1cm. Como você pode imaginar, esta frase faz com que a seta se mova para baixo de seu posição anterior (seu ponto de partida) em 1 centímetro. Essa frase destaca um aprimoramento importante do Pikchr sobre o PIC, que fez tudo em polegadas apenas. Nenhuma unidade foi permitida. Pikchr permite você anexar unidades às medidas, como neste caso onde é "1cm". Internamente, o Pikchr ainda acompanha tudo em polegadas para compatibilidade com PIC, então o token "1cm" é realmente apenas um ortografia alternativa para a constante numérica "0,39370078740157480316", que é a polegada equivalente a 1 centímetro. Certamente você concorda que "1cm" é muito mais fácil de ler e escrever! Outras unidades reconhecidas pelo Pikchr são "px" para pixels, "pt" para pontos, "mm" para milímetros, e, claro, "in" para polegadas. As polegadas são assumidas se nenhuma unidade for Especificadas.

De volta à nossa flecha: agora estabelecemos um caminho para a flecha para baixo 1 centímetro da âncora ".s" da caixa. a próxima frase é: then right until even with first cylinder ("então à direita até igualar com o primeiro cilindro"). Talvez você possa adivinhar que isso significa que a seta deve continuar para a direita até que esteja alinhado abaixo do primeiro cilindro. Você, o designer do diagrama, não sabe (e realmente não quer saber) quão distantes estão a caixa e o cilindro, então você não pode dizer exatamente o quão longe ir. Esta frase é uma maneira conveniente de dizer Pikchr para "tornar a linha longa o suficiente".

Observe que a parte firs cylinder da frase "until even with" é, na verdade, uma abreviação de first cylinder.c --- o centro do cilindro. Isto é o que queremos. você também poderia escreva first cylinder.s se quiser.

A frase until even with não é encontrada na versão original do PIC. Naquele sistema, você teria que fazer algumas contas extras para descobrir a distância, algo como then right (1st cylinder.s.x - 1st box.s.x). Nós pensamos que o a frase until even with é mais fácil de usar e entender.

A frase final na declaração da seta (arrow) é then to first cylinder.s. Esta frase diz a seta para ir de onde quer que esteja no momento diretamente para a âncora ".s" do cilindro.

Design de passagem única

Tanto o Pikchr quanto o PIC operam em um projeto de passagem única. Os objetos podem se referir a outros objetos que ocorrem antes deles no script, mas não a objetos que ocorrem posteriormente. Quaisquer cálculos que vão para a colocação de um objeto ocorrem quando a definição do objeto é analisada. Assim que a nova linha ou o ponto-e-vírgula que termina a definição do objeto é alcançado, o tamanho, localização e características do objeto são fixos e não podem ser alterados posteriormente. (Uma exceção: subobjetos que fazem parte de um contêiner [] (discutido posteriormente) são colocados em relação à origem do contêiner. Suas formas e localizações relativas entre si são fixas, mas sua posição absoluta final não é fixada até o próprio contêiner [] é fixo.)

A abordagem de passagem única contribui para a simplicidade conceitual do Pikchr (e PIC). Não existe um "resolvedor" que precise trabalhar com as restrições de layout para frente e para trás para encontrar uma solução. Essa simplicidade de design ajuda a manter os scripts do Pikchr fáceis de escrever e entender.

Rotular objetos

O exemplo anterior usou frases como first box ("primeira caixa") e first cylinder ("primeiro cilindro") para se referir a objetos específicos. Existem muitas variações neste esquema de nomenclatura:

  • previous ("anterior") ← o objeto anterior independentemente de sua classe
  • last circle ("último círculo") ← o objeto de círculo criado mais recentemente
  • 3rd ("3º último oval") ← o antepenúltimo objeto oval
  • 17th ("17ª elipse") ← o décimo sétimo objeto elipse, e assim por diante.

Essas referências relativas e ordinais funcionam, mas podem ser frágeis. Se você voltar mais tarde e inserir um novo objeto no fluxo, poderá atrapalhar a contagem. Ou, nesse caso, você pode apenas contar mal.

Em um diagrama complexo, geralmente funciona melhor atribuir nomes simbólicos a objetos, que chamamos de “rótulos” no Pikchr. Um rótulo começa com uma letra maiúscula seguida por algum número de letras ASCII regulares, dígitos ou sublinhados, seguidos por dois pontos. Isso deve vir imediatamente antes de um objeto, sem uma nova linha intermediária. Posteriormente, o objeto pode ser referido por esse rótulo.

Considere como isso simplifica nosso exemplo anterior:

B1:  box; move;
     circle; move;
     ellipse; move;
C1:  cylinder
     arrow from B1.s \ 
     down 1cm \ 
     then right until even with C1 \ 
     then to C1.s

Ao atribuir nomes simbólicos à caixa (B1) e ao cilindro (C1), a descrição do caminho da seta é simplificada. Além disso, se a elipse for alterada para outro cilindro, a seta ainda se refere ao cilindro correto.

A indentação das linhas que seguem cada nome simbólico acima é sintaticamente sem importância: serve apenas para melhorar a legibilidade humana. No entanto, este é um estilo de codificação típico para Pikchr e PIC antes dele.

Layout de objetos de bloco

Para linhas (e setas e splines), você deve especificar um caminho que a linha segue, um caminho que pode envolver várias dobras e curvas. Definir a localização dos objetos do bloco é mais fácil: basta fornecer um único local para colocar o objeto. Idealmente, você deve colocar o objeto em relação a algum outro objeto, é claro.

Digamos que você tenha uma caixa e queira posicionar um círculo 2 centímetros à direita dessa caixa. Você simplesmente usa um atributo at no círculo para dizer a ele para se posicionar 2 cm à direita da caixa:

B1: box
    circle at 2cm right of B1

O diagrama resultante é:

2cm

(Adicionamos linhas de dimensão cinza apenas para ilustração.)

O círculo é posicionado de forma que seu centro fique 2 centímetros à direita do centro da caixa. Se o que você realmente queria é que o lado esquerdo (ou oeste) do círculo esteja 2 cm à direita (ou leste) da caixa, então diga:

B1: box
C1: circle with .w at 2cm right of B1.e

Normalmente, uma cláusula at definirá o centro de um objeto, mas se você adiciona um prefixo "with" você pode especificar qualquer outra âncora ponto do objeto para ser a referência para o posicionamento. O script Pikchr acima está dizendo "faça o ponto C1.w ficar 2 cm à direita de B1.e". E nós temos:

2cm

Essa é toda a história por trás do posicionamento de objetos de bloco em um diagrama. Você acabou de adicionar um atributo do formulário:

with ponto de referência at posição

E o Pikchr colocará o ponto de referência especificado do objeto na posição. Se você omitir a cláusula with, o centro do objeto (.c) será usado como ponto de referência. O poder de Pikchr vem do fato de que "posição" pode ser uma expressão bastante complexa. O exemplo anterior usou uma posição relativamente simples de "2cm à direita de B1.e". Isso foi suficiente para o nosso diagrama simples. Diagramas mais complexos podem ter frases de posição mais complexas.

Layout Automático de Blocos de Objetos

Se você omitir o atributo at de um objeto de bloco, o objeto será posicionado como se você tivesse usado a seguinte condição:

with .start at previous.end

Exceto se o primeiro objeto no script não possuir previous e por isso é posicionado usando:

with .start at (0,0)

Vamos falar um pouco mais sobre o caso usual: with .start at previous.end. A palavra-chave previous significa o objeto anterior no script. Você também pode usar a palavra-chave last (último) para esta finalidade. Portanto, estamos posicionando o objeto atual em relação ao objeto anterior. Mas e quanto ao ".start" e ".end"?

Lembre-se que todo objeto possui 8 pontos de ancoragem cujos nomes correspondem às direções da bússola: ".n", ".ne", ".e", ".se", ".s", ".sw", ".w", e ".nw", mais a nona âncora, o ponto central ".c". Cada objeto também tem pontos de ancoragem ".start" e ".end", mas sua posição varia dependendo da direção do layout atual quando o objeto é criado.

Lembre-se do exemplo anterior que consistia em três objetos empilhados juntos:

right; box; circle; cylinder

(Eu adicionei um right no início para fazer a direção do layout claro, mas como right é a direção padrão, então não altera em nada.)

Armado com nosso novo conhecimento de como objetos de bloco sem o atributo de posição at funcionam, podemos entender melhor o que está acontecendo. A caixa é o primeiro objeto. Ele fica posicionado com seu centro em (0,0), o que podemos mostrar colocando um ponto vermelho em (0,0):

right; box; circle; cylinder
dot color red at (0,0)

Como a direção do layout é right, o início e o fim da caixa são os pontos de ancoragem .w e .e. Provamos isso colocando mais pontos coloridos nesses pontos e renderizando o resultado:

right; box; circle; cylinder
dot color green at 1st box.start
dot color blue at 1st box.end

Da mesma forma, podemos mostrar que o início e o fim do círculo são seus pontos de ancoragem .w e .e. (Adicione novos pontos coloridos para provar isso a si mesmo, se quiser.) E claramente, o início do círculo está diretamente no topo do final da caixa.

Agora considere o que acontece se mudarmos a direção do layout após o o círculo ser criado, mas antes do cilindro ser criado:

right; box; circle; down; cylinder

Este script funciona de maneira um pouco diferente no Pikchr e no PIC. A mudança de comportamento é deliberada, pois acretitamos que essa nova abordagem no Pikchr é melhor. No PIC, o diagrama acima seria renderizado assim:

Mas no Pikchr a colocação do cilindro é diferente:

Vamos separar o que está acontecendo aqui. Em ambos os sistemas, após o objeto "círculo" ser analisado e posicionado, o .end do círculo é o mesmo que o .e, porque a direção do layout é right. Podemos omitir o down e cylinder e desenhar um ponto no .end do círculo para ver isso:

A próxima instrução é down. A instrução down altera o layout direção para down em ambos os sistemas. No PIC, o fim do círculo permanece na âncora .e. Então, quando o "cilindro" é posicionado, seu .start está em .n porque a direção do layout agora está down, então o ponto .n do cilindro está alinhado ao ponto .e do o circulo.

O Pikchr funciona como o PIC com uma alteração importante: quando a instrução down é avaliado, o Pikchr também move o .end do objeto anterior para um novo local apropriado para a nova direção. em outras palavras, o comando down move a extremidade do círculo de .e para .s. Você pode ver isso definindo um ponto vermelho no final do círculo depois do comando down:

Ou, podemos "imprimir" as coordenadas do .end do círculo antes e depois do comando down para ver que eles mudam:

antes: 0.875 , 0
depois: 0.625 , -0.25

Ajustando o tamanho dos blocos

O tamanho de cada bloco é controlado por três parâmetros:

  • width (frequentemente abreviado como wid)
  • height (ou ht)
  • radius (ou rad)

Há também um quarto parâmetro de conveniência:

  • diameter

O diameter é sempre o dobro do raio. Definindo o diameter automaticamente altera o radius e definir o radius altera automaticamente o diameter.

Normalmente, os significados desses parâmetros são óbvios.

height width

O parâmetro radius, no entanto, às vezes tem significados não óbvios. Por exemplo, em uma caixa, o "raio" determina o arredondamento dos cantos:

height width radius

Para um objeto cilíndrico, o "raio" determina a espessura das tampas:

height width radius

Para um arquivo, o "raio" determina o tamanho da página dobrada no canto superior direito:

height width radius

Para um círculo, a largura, a altura e o diâmetro são sempre iguais e o raio é sempre a metade do diâmetro. Mudando qualquer parâmetro ajusta automaticamente os outros três.

height width radius  diameter

Mesmo que sejam objetos curvos, o "raio" (e, portanto, "diâmetro") não tem efeito em objetos tiop ellipse e oval. O tamanho desses objetos é determinado puramente por sua largura e altura:

height width height width height width

Observe que com um objeto oval, a tampa semicircular é sempre na extremidade estreita do objeto. Na configuração padrão onde a altura é menor que a largura, as tampas semicirculares estão na esquerda e direita, mas se a largura e a altura forem modificadas para que o largura é menor que a altura, então os semicírculos aparecem no topo e inferior em vez disso.

Tamanhos Padrão

Os objetos de bloco têm tamanhos padrão, que são determinados por variáveis. Por exemplo, a largura de uma caixa é inicializada com o valor da variável boxwid, cujo padrão é 0.75in.

É comum para scripts Pikchr alterar esses padrões no início ou próximo a ele para ajustar os tamanhos dos objetos.

Definindo os tamanhos usando atributos

Use o atributo width (ou wid) para alterar a largura de um objeto. O argumento para este atributo pode ser uma expressão — como 1cm ou 0.75*boxwid — ou pode ser uma porcentagem do valor anterior, como 75%. Isso também funciona para height, raio e diâmetro.

Dimensionamento automático para ajustar anotações de texto

Se um objeto de bloco contém anotações de texto, o atributo fit causa a largura e a altura serem ajustadas para que o objeto envolva perfeitamente o texto. O atributo fit considera apenas o texto previamente definido para o objeto, ou em outras palavras, anotações de texto que ocorrem à esquerda da palavra-chave fit. A largura e a altura podem ser ajustadas ainda mais após a palavra-chave "fit", por exemplo, para fornecer uma margem maior em torno do texto. O script a seguir apresenta a diferença que o comando largura 125% faz no final da segunda definição de caixa.

down
box "Auto-fit text annotation" "as is" fit
move 50%
box "Auto-fix text annotation" "with 125% width" fit width 125%
Texto com auto-ajuste padrão Texto com auto-ajuste de 125% na largura

Se no final de uma definição de objeto de bloco, a largura ou a altura do objeto é menor ou igual a zero, então essa dimensão é aumentada de modo a incluir todas as anotações de texto no objeto. Assim, por exemplo, você pode fazer todas as caixas em seu diagrama se ajustam automaticamente em torno de suas anotações de texto, precedendo seu script com algo como:

boxwid = 0; boxht = 0;
box "Olá";
move
box "Um *label* mais longo" "com múltiplas linhas" "de texto"
Olá Um label mais longo com múltiplas linhas de texto

Para todos esses recursos de ajuste automático, o Pikchr precisa saber as dimensões das anotações de texto após a renderização. Infelizmente, essa informação não é prontamente disponível, pois o Pikchr é executado muito antes de o SVG gerado atingir o navegador da Web no qual será exibido. Assim, Pikchr tem que adivinhar o Tamanho do texto. Normalmente faz um bom trabalho nisso, mas pode cometer alguns erros, especialmente para caracteres incomuns (leia-se: "não-ASCII") ou se o CSS para o ambiente de renderização define uma fonte ou tamanho de fonte não padrão. Para compensar, as variáveis charwid e charht podem ser ajustadas ou espaços extras podem ser adicionados no início ou no final das cadeias de texto.

Esses recursos de ajuste automático são uma inovação do Pikchr e não estão disponíveis em outros interpretadores da família PIC, até onde sabemos.

Atributos para largura do traçado e cores

Vários atributos podem ser adicionados aos blocos e linhas para influenciar como os objetos são desenhados.

  • thickness dimensão
  • thick
  • thin
  • invisible (ou invis)
  • color cor
  • fill cor

Os atributos thickness, thick, thin e invisible controla a largura do traçado das linhas que constroem um objeto. A largura padrão do traçado para todos os objetos é determinado pela variável thickness, cujo padrão é 0.015in. Os atributos thick e thin aumentam ou diminuem a largura do traçado por porcentagens fixas. Esses atributos podem ser repetidos para tornar a largura do traço cada vez mais grossa ou mais fina, até o limite das dimensões em que o traçado preenche todo o objeto. O atributo invisible simplesmente define a largura do traçado como 0.

normal thin thick thick thick thick invisível

Observe que “invisível” refere-se apenas ao contorno do objeto, não ao objeto inteiro. Portanto, você cancela o atributo invisible com solid, não “visible”:

 boxwid = 0
 boxht = 0
 box "totalmente visível"
 box invisible color gray "linha invisível"
 box same solid "linha visível novamente" fit
totalmente visível linha invisível linha visível novamente

Os atributos color e fill alteram as cores do primeiro plano e do plano de fundo de um objeto. As cores podem ser expressas usando qualquer um dos 148 padrões Nomes de cores CSS como "Bisque" ou "AliceBlue" ou "LightGray". Os nomes das cores não diferenciam maiúsculas de minúsculas, então "bisque", "BISQUE" e "Bisque" significam a mesma coisa. Os nomes das cores também podem ser expressos como um número inteiro, que é interpretado como um valor RGB de 24 bits. É conveniente expressar os valores de cor usando a notação hexadecimal. "Bisque" é o mesmo que "0xffe4c4", que é o mesmo que "16770244".

Color: CadetBlue Fill: Bisque Color: White Fill: RoyalBlue

Definir o fill como um número negativo, "None" ou para "Off" faz com que fundo fique transparente (padrão). A cor de primeiro plano padrão é preta.

Polígonos preenchidos

O atributo fill não afeta a renderização das linhas a menos que o rota da linha seja terminada pelo atributo close. A palavra-chave close converte a linha em um polígono:

line go 3cm heading 150 then 3cm west close \ 
  /* ^^^^^ nota bene! */  \ 
  fill 0x006000 color White "Triângulo" below "verde" below
Triângulo verde

Os polígonos não precisam ter uma cor de preenchimento. O preenchimento padrão é None, você pode usar a palavra-chave close para converter um polígono em uma linha e deixar o fundo transparente, basta usar fill cor" junto com close em uma expressão comum.

Anotações de texto

Cada objeto pode ter até cinco linhas de anotação de texto. Cada anotação é um atributo literal de string na definição do objeto. Por padrão, as anotações são exibidas ao redor do centro do objeto, de cima para baixo, na ordem em que aparecem no script de entrada.

box "Caixa contendo" "três linhas" "de texto" fit
move
arrow "Linha" "rotulada" wid 200%
Caixa contendo três linhas de texto Linha rotulada

Atributos de texto

O layout e o estilo da fonte das anotações podem ser modificados usando palavras-chave que aparecem após cada string literal. Os seguintes modificadores são suportados:

  • above
  • aligned
  • below
  • big
  • bold
  • mono
  • monospace
  • center
  • italic
  • ljust
  • rjust
  • small

Posicione o texto acima ou abaixo do centro do objeto

As palavras-chave above e below controlam a localização do texto acima ou abaixo do ponto central do objeto com o qual o texto está associado. Se houver apenas um texto no objeto e as palavras-chave above e below são omitidas, o texto é colocado diretamente sobre o centro do objeto. Isso causa o texto a aparecer no meio das linhas:

line "on the line" wid 150%
sobre a linha

Então, se houver apenas um único rótulo de texto em uma linha, você provavelmente deseja incluir a palavra-chave above" ou "below".

line "above" above; move; line "below" below
above below

Se houver dois textos no objeto, eles ocupam o ponto central acima e abaixo, mesmo sem o uso das palavras-chave above e under:

line wid 300% "texto sem "above"" "texto sem "below""
texto sem  texto sem 

Os atributos above e below não se acumulam. Cada acima ou abaixo substitui qualquer acima ou abaixo anterior para o mesmo texto.

Se houver vários textos e todos estiverem marcados como "acima" ou "abaixo", então todos são colocados acima ou abaixo do ponto central, em ordem de aparição.

line width 200% "primeiro "above"" above "segundo "above"" above
move
line same "primeiro "below"" below "segundo "below"" below
primeiro  segundo  primeiro  segundo 

Justifique o texto à esquerda ou à direita

Assim como as palavras-chave above e below controlam o posicionamento para cima e para baixo do texto, as palavras-chave ljust e rjust controlam o posicionamento a esquerda e a direita.

Para uma linha, o ljust significa que o lado esquerdo do texto está nivelado contra o ponto central da linha, e rjust significa que o lado direito lado do texto está nivelado com o ponto central da linha.

(No diagrama a seguir, o ponto vermelho está no centro da linha.)

line wid 200% "ljust" ljust above "rjust" rjust below
dot color red at previous.c
ljust rjust

Para um objeto, ljust desloca o texto para ser justificado à esquerda contra a borda esquerda do bloco (com uma pequena margem) e rjust coloca o texto contra o lado direito do objeto (com mesma margem).

box "ljust" ljust "longer line" ljust "even longer line" ljust fit
move
box "rjust" rjust "longer line" rjust "even longer line" rjust fit
ljust longer line even longer line rjust longer line even longer line

O comportamento de ljust e rjust para objetos no Pikchr é diferente do PIC. No PIC, o texto é sempre justificado em torno do ponto central, como nas linhas, mas isso significa que não há uma maneira fácil de justificar à esquerda várias linhas de texto dentro de uma "caixa" ou "arquivo", então o comportamento foi alterado para Pikchr.

Pikchr permite cinco objetos de texto separados dentro de outro objeto combinando ljust, rjust e a centralização de texto padrão:

box wid 300% 
   "above-ljust" above ljust 
   "above-rjust" above rjust 
   "centered" center 
   "below-ljust" below ljust 
   "below-rjust" below rjust
above-ljust above-rjust centered below-ljust below-rjust

Atributo de texto center

O atributo center cancela todos os anteriores above, below, ljust e
rjust para o objeto de texto atual.

Estilos de fonte em negrito e itálico

Os atributos bold e italic fazem com que o objeto de texto use negrito ou fonte em itálico. As fontes podem ser negrito e itálico ao mesmo tempo:

box "bold" bold "italic" italic "bold-italic" bold italic fit
bold italic bold-italic

Família de fontes monospace

Os atributos mono ou monospace fazem com que o objeto de texto use uma fonte monoespaçada.

box "monospace" monospace fit
monospace

Texto alinhado

O atributo aligned faz com que o texto associado a uma linha reta para ser girado para alinhar com essa linha:

arrow go 150% heading 30 "aligned" aligned above
move to 1cm east of previous.end
arrow go 150% heading 170 "aligned" aligned above
move to 1cm east of previous.end
arrow go 150% north "aligned" aligned above
aligned aligned aligned

Para exibir um texto girado não associado a uma linha, anexe o texto para uma linha marcada como invisible

box ht 200% wid 50%
line invis from previous.s to previous.n "texto rotacionado" aligned
texto rotacionado

Observe que a direção do texto alinhado é a mesma que a direção da própria linha, então se você desenhar uma linha da direita para a esquerda, o alinhamento o texto aparecerá de cabeça para baixo:

circle "C1" fit
circle "C0" at C1+(2.5cm,-0.3cm) fit
arrow from C0 to C1 "aligned" aligned above chop
C1 C0 aligned

Se você precisar de texto alinhado em uma seta que vai da direita para a esquerda, e você não quer que o texto seja renderizado de cabeça para baixo, desenhe a seta da esquerda para a direita e inclua o atributo <- de modo que a ponta da seta esteja no início e não no final:

circle "C1" fit
circle "C0" at C1+(2.5cm,-0.3cm) fit
arrow from C1 to C0 "aligned" aligned above <- chop
C1 C0 aligned

Ajustando o tamanho da fonte

Os atributos big e small fazem com que o texto fique um pouco maior ou um pouco menor, respectivamente. Dois atributos big fazem com que o texto seja ainda maior; da mesma forma, dois atributos small tornam o texto ainda menor. O tamanho do texto não aumenta ou diminui além de duas palavras-chave big ou small.

box "small small" small small "small" small 
    "(normal)" italic 
    "big" big "big big" big big ht 200%
small small small (normal) big big big

Uma palavra-chave big cancela qualquer palavra-chave small anterior no mesmo texto, e uma palavra-chave small cancela qualquer palavra-chave big anterior.

O texto é posicionado ao redor do centro do objeto

O ponto de ancoragem para anotações de texto geralmente é o centro da caixa delimitadora para todo o objeto. Isso é intuitivo para objetos e linhas retas. Mas para linhas de vários segmentos, o texto pode não estar próximo a própria linha. Por exemplo, na seta de quatro segmentos a seguir, a caixa vermelha é a caixa delimitadora e o ponto vermelho mostra o centro da caixa delimitadora. O rótulo de texto é alinhado em relação ao centro do caixa delimitadora, que não está próxima a nenhuma parte da linha real.

arrow up 1.5cm right 1.5cm then down .5cm right 1cm then up .5cm right .3cm 
   then down 2.5cm right 1cm "texto"
box color red thin thin width previous.wid height previous.ht 
   with .c at previous.c
dot at last arrow.c color red behind last arrow
text

Se você precisar posicionar o texto ao lado de um segmento específico de um segmento múltiplo, considere criar uma linha invis separada por cima dessa linha e anexando o texto à linha "invis". Aqui está a mesma seta de antes, mas com o texto anexado a uma linha "invisível" separada que sobrepõe o segundo segmento da seta:

arrow up 1.5cm right 1.5cm then down .5cm right 1cm then up .5cm right .3cm 
   then down 2.5cm right 1cm
box color red thin thin width previous.wid height previous.ht 
   with .c at previous.c
dot at last arrow.c color red behind last arrow
line invis from 2nd vertex of last arrow to 3rd vertex of last arrow 
   "texto" below aligned
texto

O ponto de ancoragem do texto é geralmente o centro do objeto, mas em alguns casos, o ponto de ancoragem pode ser um pouco "pertubado". Isto acontece, por exemplo, para objetos de cilindro:

C1: cylinder "texto em um" "cilindro" rad 120%
    dot color red at C1.c
    dot color blue at 0.75*C1.rad below C1.c
texto em um cilindro

O ponto vermelho está no centro do cilindro e o ponto azul mostra o ponto de ancoragem para o texto. O ponto de ancoragem é um mais baixo para cilindros pois isso parece melhor visualmente. Sem esse ajuste do ponto central do texto, o texto do cilindro ficaria estranho:

C1: cylinder rad 120%
    text "texto em um" "cilindro" at C1.c
texto em um cilindro

Blocos ou Containers

Um container é uma lista de um ou mais objetos contidos em [...]. É uma coleção de um ou mais objetos que se parece com um único para o restante do script.

Por exemplo:

A: [
    oval "Olá"
    arrow
    box "Mundo" radius 4px
    ]
Border: box thin width A.width+0.5in height A.height+0.5in at A.center
Olá Mundo

O recipiente "A" é composto por uma forma oval, uma seta e uma caixa com cantos. Mas para a caixa "Border" subsequente, o contêiner "A" parece ser um único objeto. A caixa de borda pode fazer referência à largura e altura gerais e o ponto central do contêiner A para dimensionar e posicionar-se para criar um caixa com uma borda de 0,25 pol:

A: [
  oval "Olá"
  arrow
  box "Mundo" radius 4px
]
Border: box thin width A.width+0.5in height A.height+0.5in at A.center
Olá Mundo

Um contêiner é útil principalmente para adicionar uma borda ao redor de uma coleção de objetos, como mostrado acima, ou adicionar uma legenda a um diagrama. A seguir mostramos como uma legenda pode parecer.

A: [
  oval "Olá"
  arrow
  box "Mundo" radius 4px
  ]
Titulo: text "Título do diagrama" italic with .n at 0.1in below A.s
Olá Mundo Título do diagrama

No PIC tradicional, a direção do layout muda (os comandos up, down, left e right) e as definições de variáveis dentro de um contêiner afetam apenas as declarações dentro do mesmo contêiner. Uma vez que o contêiner encerra, a direção anterior e os valores das variáveis são restaurados. O Pikchr não funciona dessa maneira. Em Pikchr, mudanças de direção de layout e definições de variáveis que ocorrem dentro um contêiner continua em vigor após o contêiner.

Ordem de empilhamento de objetos

Os objetos são normalmente desenhados na ordem em que são definidos. Por isso objetos que estão no final do script que se sobrepõem a objetos perto do início parecerá estar no topo.

Algumas vezes é desejável que um objeto posterior pareça estar atrás de um objeto inicial. Isso é útil, por exemplo, ao usar uma caixa para formar um fundo colorido para um grupo de objetos anteriores. O atributo behind com um argumento que é o rótulo para qualquer objeto anterior pode ser adicionado para fazer com que o objeto que o contém sejá desenhado antes do objeto referenciado.

Resumo e conclusão

Embora baseado na linguagem PIC de décadas, o próprio Pikchr é relativamente novo sistema. No entanto, já provou ser incrivelmente útil para ajudando a ilustrar conceitos em documentação técnica escrita usando Markdown.

Este documento forneceu uma visão geral de como o Pikchr funciona. Para mais detalhes e outras perspectivas, consulte os seguintes recursos:

Disclaimer Algums dos exemplos a seguir foram retirados do projeto pikchr.

/*
 Processos. André Leite (leite@castlab.org)
 */

margin = .25cm
$gr = 1.618
$altura = .25
$largura = 2

B1: box "Chegada" rad .5 width $largura height $altura
L1: line -> down .25 from B1.s + ($largura/4,0)
B2: box "Regulação" rad .05 fit
L2: line -> down .25 from B1.s - ($largura/4,0)
B3: box "Espontânea" rad .05 fit
L3: line from B2.s down .25 then left until even with B3.s then to B3.s
D1: dot at L3.s
L4: line down .25 -> 
  X: diamond wid .25 ht .25
L5: line "Sim" small above ljust left from X.w ->
  B4: box "Sala de Emergência" rad .05 fit  wid .6*$largura
L6: line -> down .25 from B4.s 
B5: box "Atendimento Médico" "Imediato" bold fit rad .05 fill 0xff6b6b color none wid .6*$largura
L7: line from X.e right -> "Não" small above rjust
B6: box "Acolhimento" fit rad .05  wid .6*$largura
L8: line -> from B6.s down until even with B5.n 
B7: box "Sinais Vitais" "Téc. de Enfermagem" small bold fit rad .1  wid .6*$largura
L9: line -> from B7.s down .25
B8: box  "Classificação de Risco" "Enfermeiro" small bold fit rad .1  wid .6*$largura
L10: line right .125 from B8.e then down .6 ->
  X1: diamond wid .25 ht .25 fill 0x2171b5
L11: line down .125 -> 
  B9: box "Encaminhamento" "para UBS" fit rad .1  wid .5*$largura
L12: line from L10.end + (0, .25) left 1.25 then down .25 ->
  X2: diamond wid .25 ht .25 fill 0x74c476
L11: line down .125 -> 
  B10: box "Atendimento Médico" "em até 120 minutos" bold fit rad .1 wid .5*$largura
L13: line from L12.nw left 1.25 then down .25 ->
  X3: diamond wid .25 ht .25 fill 0xfaff00
L12: line down .125 -> 
  B11: box "Atendimento Médico" "em até 60 minutos" bold fit rad .1  wid .5*$largura
L14: line from L13.nw left 1.25 then down .25 ->
  X3: diamond wid .25 ht .25 fill 0xf16913
L14: line down .125 -> 
  B12: box "Atendimento Médico" "em até 10 minutos" bold fit rad .1  wid .5*$largura
"Emergência?" small at X.s - (0, .075)
Chegada Regulação Espontânea Sim Sala de Emergência Atendimento Médico Imediato Não Acolhimento Sinais Vitais Téc. de Enfermagem Classificação de Risco Enfermeiro Encaminhamento para UBS Atendimento Médico em até 120 minutos Atendimento Médico em até 60 minutos Atendimento Médico em até 10 minutos Emergência?
/*
 Exemplo 1. André Leite (leite@castlab.org)
 */
/*  1 */ dimen_ = 1
/*  2 */ Origem: (0,0) 
/*  3 */ B1:box "Microfone";
/*  4 */ L1:line from B1.e right dimen_/2;
/*  5 */ L2:line -> up dimen_/3.2 then right dimen_/2;
/*  6 */ L3:line -> from L1.end down dimen_/3.2 then right dimen_/2; 
/*  7 */ B2:box "Filtro PF" "em f₀" with .w at L2.end;
/*  8 */ B3:box "Filtro PF" "em f₁" with .w at L3.end;
/*  9 */ L4:line -> from B2.e right dimen_/2 then down dimen_/3.2 
/* 10 */     then right dimen_/2 
/* 11 */ L4:line -> from B3.e right dimen_/2 then up dimen_/3.2 
/* 12 */     then right dimen_/2 
/* 13 */ B4: box "Rede" "Neural" with .w at (L4.end.x,L1.end.y)         
Microfone Filtro PF em f₀ Filtro PF em f₁ Rede Neural
/*
 Exemplo 2. André Leite (leite@castlab.org)
 */
dimen_= .75
Origem:(0,0) 
B1:box "Agente" "Externo";
L1:line -> from B1.s down dimen_/4 then left 1.5*dimen_ then down dimen_/4; 
B2:box wid 1 "Sensores" "Digitais";
L2:line -> from B1.s down dimen_/4 then right 1.5*dimen_ then down dimen_/4;
B3:box wid 1 "Sensores" "Analógicos";
L3:line -> from B2.s down dimen_/2;
B4:box wid 1 "Transmissor" "FSK";
L4:line -> from B3.s down dimen_/2; 
B5:box wid 1 "Transmissor" "FM"; 
L5:line -> from B4.s down dimen_/2; 
B6:box wid 1 "Receptor" "FSK";
L6:line -> from B5.s down dimen_/2; 
B7:box wid 1 "Receptor" "FM";
L7:line -> from B6.s down .5*dimen_ then right 4.5*dimen_ \ 
    then up 3*dimen_ then right .5*dimen_ 
L8:line -> from B7.s down .25*dimen_ then right 1.25*dimen_ \ 
    then up 3*dimen_  then right .75*dimen_
B8:box wid 1 "Rede" big "Neural" big with .w at 1/2<L7.end, L8.end> fill lightblue
L9:line -> from B8.e right dimen_;
B9:box wid 1 "Sistema de" "Controle" "de Acesso";
L10:line -> from B8.e+(0,boxht/6) right dimen_/2 then up dimen_ then right dimen_/2; 
B10:box wid 1 "Sistema de" "Alarme";
L11:line -> from B8.e-(0,boxht/6) right dimen_/2 then down dimen_ then right dimen_/2; 
B11:box wid 1 "Sistema de" "Anúncio";         
Agente Externo Sensores Digitais Sensores Analógicos Transmissor FSK Transmissor FM Receptor FSK Receptor FM Rede Neural Sistema de Controle de Acesso Sistema de Alarme Sistema de Anúncio
/*
 Exemplo 3. André Leite (leite@castlab.org)
 */
               $len = 175px;
               margin = 20px;
/* First Stage */
          B1E: box rad 5px wid 2*$len fill white;
    LineCusto: line <- from B1E.n - ((2/3)*$len,0) up .25*$len;
     BoxCusto: box rad 5px "Custo" wid .5*$len ht .25*$len fill 0xFFD320;
LineDistancia: line <- thick from BoxCusto.w + (0,.25*$len/6) left .25*$len/2 \ 
                    then up .25*$len/6 then left .15*$len/2;
               box rad 10px "Distância" fit wid .35*$len fill 0xFFD320;
    LineTempo: line <- thick  from BoxCusto.w - (0,.25*$len/6) left .25*$len/2 \ 
                    then down .25*$len/6  then left .15*$len/2 color gray;
               box rad 10px "Tempo" fit wid .35*$len fill 0xFFD320;
               text "Primeiro Estágio" bold at B1E.c  color black;
   LineNumMat: line <- from B1E.n - ((0)*$len,0) up .25*$len;
           NM: box rad 10px fill 0x004586 ht .25*$len wid .6*$len;
 LineDemRisco: line <- from B1E.n + ((2/3)*$len,0) up .25*$len;
           NR: box rad 10px  wid .6*$len fill 0x7E0021 ht .25*$len;
               text "Número de Novas" "Maternidades" at NM.c color white;
               text "Nascimentos" "de risco" at NR.c color white;
/*Second Stage */
          B2E: box rad 5px with .n at B1E.s - (0, (.6)*$len) wid 2*$len fill white;
    LineOfeta: line <- from B2E.n up .2*$len;
           OF: box rad 10px "Nascimentos" "no município" fit wid .5*$len fill 0xFF420E;
  LineDemanda: line <- from B2E.n - ((2/3)*$len,0) up .2*$len;
           DM: box rad 10px "Nascimentos" "de residentes" fit wid .5*$len fill 0x83CAFF;
LineResultado: line -> "Polos" aligned above italic from B2E.e right .35*$len;
           RS: file "Resultado" bold ht .25*$len wid .5*$len fill 0x579D1C;
   LineSegEst: line -> "Macropolos" above italic aligned from B1E.s + ((2/3)*$len,0) down .6*$len; 
               text "Segundo Estágio" bold at B2E.c color black;
           BX: box thin dashed with .c at 1/2<OF.c,DM.c> wid 1.35*$len ht OF.height + .2;
               text "Município" above at BX.n;
/* Fim */          
Custo Distância Tempo Primeiro Estágio Número de Novas Maternidades Nascimentos de risco Nascimentos no município Nascimentos de residentes Polos Resultado Macropolos Segundo Estágio Município
/*
 Exemplo 4. André Leite (leite@castlab.org)
 */
dimen_ = .75
L1:line -> right dimen_/2; 
"RF" rjust at L1.w - (.05,0)
C1:circle radius dimen_/4 with .w at L1.e 
L2:line -> from C1.e right dimen_/2
B1:box " A " wid dimen_ ht dimen_*3/4
L3:line -> right dimen_;
L4:line -> from L3.c down dimen_*1 then left dimen_/2; 
B4:box "B" wid dimen_ ht dimen_*3/4
L7:line -> left (B4.w.x-C1.c.x) then up to C1.s
"+" at C1.c
B2:box with .w at L3.e "Detetor de" "envelope" wid dimen_ ht dimen_*3/4
L5:line -> from B2.e right dimen_/2; 
"BF" ljust at L5.end + (.05,0)
L6:line <- from B1.n up dimen_/2;
B3:box "oscilador" ht dimen_/2 wid dimen_*3/4         
RF  A  B + Detetor de envelope BF oscilador
/*
 Exemplo 5. André Leite (leite@castlab.org)
 */
linethick *= 1.5 
dimen_ = 1 
j = dimen_*sqrt(3)/2 
i = dimen_/2
define cell { 
    move to ($2,$3)
    A:line up dimen_*sqrt(3)/2 right dimen_/2 
    B:line right dimen_ 
    C:line down dimen_*sqrt(3)/2 right dimen_/2 
    D:line down dimen_*sqrt(3)/2 left dimen_/2
    E:line left dimen_
    F:line up dimen_*sqrt(3)/2 left dimen_/2 
    text $1 at A.start + (dimen_,0)
    move to C.end
}

cell("",0,0)
dimen_ *= 0.5 
cell("",0,0)
cell("",3*i/2,j/2)
cell(,3*i/2,-j/2)         
/*
 Exemplo 5. Original em pikchr.org e fossil-scm.org
 */
     scale = 0.8
     fill = white
     linewid *= 0.5
C0:  circle "C₀" fit
     circlerad = previous.radius
     arrow
C1:  circle "C₁"
     arrow
C2:  circle "C₂"
     arrow
C4:  circle "C₄"
     arrow
C6:  circle "C₆"
C3:  circle "C₃" at dist(C2,C4) heading 30 from C2
     arrow
C5:  circle "C₅"
     arrow from C2 to C3 chop
C3P: circle "C₃'" at dist(C4,C6) heading 30 from C6
     arrow right from C3P.e
C5P: circle "C₅'"
     arrow from C6 to C3P chop

     box height C3.y-C2.y \ 
        width (C5P.e.x-C0.w.x)+linewid \ 
        with .w at 0.5*linewid west of C0.w \ 
        behind C0 \ 
        fill 0xc6e2ff thin color gray
        
     box same width previous.e.x - C2.w.x \ 
        with .se at previous.ne \ 
        fill 0x9accfc
        "trunk" below at 2nd last box.s
        "feature branch" above at last box.n
C₀ C₁ C₂ C₄ C₆ C₃ C₅ C₃' C₅' trunk feature branch
/*
 Exemplo 6. Original em pikchr.org e fossil-scm.org
 */
linewid *= 0.5
circle "C0" fit
circlerad = previous.radius
arrow
circle "C1"
arrow
circle "C2"
arrow
circle "C4"
arrow
circle "C6"
circle "C3" at dist(C2,C4) heading 30 from C2

d1 = dist(C2,C3.ne)+2mm
line thin color gray from d1 heading 30 from C2 \ 
   to d1+1cm heading 30 from C2
line thin color gray from d1 heading 0 from C2 \ 
   to d1+1cm heading 0 from C2
spline thin color gray <-> \ 
   from d1+8mm heading 0 from C2 \ 
   to d1+8mm heading 10 from C2 \ 
   to d1+8mm heading 20 from C2 \ 
   to d1+8mm heading 30 from C2 \ 
   "30&deg;" aligned below small

X1: line thin color gray from circlerad+1mm heading 300 from C3 \ 
        to circlerad+6mm heading 300 from C3
X2: line thin color gray from circlerad+1mm heading 300 from C2 \ 
        to circlerad+6mm heading 300 from C2
line thin color gray <-> from X2 to X1 "distância" aligned above small \ 
    "C2 para C4" aligned below small
C0 C1 C2 C4 C6 C3 30° distância C2 para C4
/*
 Exemplo 7. Original em pikchr.org e fossil-scm.org
 */
lineht *= 0.4
$margin = lineht*2.5
scale = 0.75
fontscale = 1.1
charht *= 1.15
down

In: box "Interface" wid 150% ht 75% fill white
    arrow
CP: box same "SQL Command" "Processor"
    arrow
VM: box same "Virtual Machine"
    arrow down 1.25*$margin
BT: box same "B-Tree"
    arrow
    box same "Pager"
    arrow
OS: box same "OS Interface"
    box same with .w at 1.25*$margin east of 1st box.e "Tokenizer"
    arrow
    box same "Parser"
    arrow
CG: box same ht 200% "Code" "Generator"
UT: box same as 1st box at (Tokenizer,Pager) "Utilities"
    move lineht
TC: box same "Test Code"
    arrow from CP to 1/4<Tokenizer.sw,Tokenizer.nw> chop
    arrow from 1/3<CG.nw,CG.sw> to CP chop

    box ht (In.n.y-VM.s.y)+$margin wid In.wid+$margin \ 
       at CP fill 0xd8ecd0 behind In
    line invis from 0.25*$margin east of last.sw up last.ht \ 
        "Core" italic aligned

    box ht (BT.n.y-OS.s.y)+$margin wid In.wid+$margin \ 
       at Pager fill 0xd0ece8 behind In
    line invis from 0.25*$margin east of last.sw up last.ht \ 
       "Backend" italic aligned

    box ht (Tokenizer.n.y-CG.s.y)+$margin wid In.wid+$margin \ 
       at 1/2<Tokenizer.n,CG.s> fill 0xe8d8d0 behind In
    line invis from 0.25*$margin west of last.se up last.ht \ 
       "SQL Compiler" italic aligned

    box ht (UT.n.y-TC.s.y)+$margin wid In.wid+$margin \ 
       at 1/2<UT,TC> fill 0xe0ecc8 behind In
    line invis from 0.25*$margin west of last.se up last.ht \ 
      "Accessories" italic aligned
Interface SQL Command Processor Virtual Machine B-Tree Pager OS Interface Tokenizer Parser Code Generator Utilities Test Code Core Backend SQL Compiler Accessories
/*
 Exemplo 8. Original em pikchr.org e fossil-scm.org
 */         
$r = 0.2in
linerad = 0.75*$r
linewid = 0.25

# Start and end blocks
#
box "element" bold fit
line down 50% from last box.sw
dot rad 250% color black
X0: last.e + (0.3,0)
arrow from last dot to X0
move right 3.9in
box wid 5% ht 25% fill black
X9: last.w - (0.3,0)
arrow from X9 to last box.w


# The main rule that goes straight through from start to finish
#
box "object-definition" italic fit at 11/16 way between X0 and X9
arrow to X9
arrow from X0 to last box.w

# The LABEL: rule
#
arrow right $r from X0 then down 1.25*$r then right $r
oval " LABEL " fit
arrow 50%
oval "\":\"" fit
arrow 200%
box "position" italic fit
arrow
line right until even with X9 - ($r,0) \ 
  then up until even with X9 then to X9
arrow from last oval.e right $r*0.5 then up $r*0.8 right $r*0.8
line up $r*0.45 right $r*0.45 then right

# The VARIABLE = rule
#
arrow right $r from X0 then down 2.5*$r then right $r
oval " VARIABLE " fit
arrow 70%
box "assignment-operator" italic fit
arrow 70%
box "expr" italic fit
line right until even with X9 - ($r,0) \ 
  then up until even with X9 then to X9

# The PRINT rule
#
arrow right $r from X0 then down 3.75*$r then right $r
oval "\"print\"" fit
arrow
box "print-args" italic fit
line right until even with X9 - ($r,0) \ 
  then up until even with X9 then to X9

element object-definition  LABEL  ":" position  VARIABLE  assignment-operator expr "print" print-args
/*
 Exemplo 9. Original em pikchr.org e fossil-scm.org
 */
    $laneh = 0.75

    # Draw the lanes
    down
    box width 3.5in height $laneh fill 0xacc9e3
    box same fill 0xc5d8ef
    box same as first box
    box same as 2nd box
    line from 1st box.sw+(0.2,0) up until even with 1st box.n \ 
      "Alan" above aligned
    line from 2nd box.sw+(0.2,0) up until even with 2nd box.n \ 
      "Betty" above aligned
    line from 3rd box.sw+(0.2,0) up until even with 3rd box.n \ 
      "Charlie" above aligned
    line from 4th box.sw+(0.2,0) up until even with 4th box.n \ 
       "Darlene" above aligned

    # fill in content for the Alice lane
    right
A1: circle rad 0.1in at end of first line + (0.2,-0.2) \ 
       fill white thickness 1.5px "1" 
    arrow right 50%
    circle same "2"
    arrow right until even with first box.e - (0.65,0.0)
    ellipse "future" fit fill white height 0.2 width 0.5 thickness 1.5px
A3: circle same at A1+(0.8,-0.3) "3" fill 0xc0c0c0
    arrow from A1 to last circle chop "fork!" below aligned

    # content for the Betty lane
B1: circle same as A1 at A1-(0,$laneh) "1"
    arrow right 50%
    circle same "2"
    arrow right until even with first ellipse.w
    ellipse same "future"
B3: circle same at A3-(0,$laneh) "3"
    arrow right 50%
    circle same as A3 "4"
    arrow from B1 to 2nd last circle chop

    # content for the Charlie lane
C1: circle same as A1 at B1-(0,$laneh) "1"
    arrow 50%
    circle same "2"
    arrow right 0.8in "goes" "offline"
C5: circle same as A3 "5"
    arrow right until even with first ellipse.w \ 
      "back online" above "pushes 5" below "pulls 3 &amp; 4" below
    ellipse same "future"

    # content for the Darlene lane
D1: circle same as A1 at C1-(0,$laneh) "1"
    arrow 50%
    circle same "2"
    arrow right until even with C5.w
    circle same "5"
    arrow 50%
    circle same as A3 "6"
    arrow right until even with first ellipse.w
    ellipse same "future"
D3: circle same as B3 at B3-(0,2*$laneh) "3"
    arrow 50%
    circle same "4"
    arrow from D1 to D3 chop
Alan Betty Charlie Darlene 1 2 future 3 fork! 1 2 future 3 4 1 2 goes offline 5 back online pushes 5 pulls 3 & 4 future 1 2 5 6 future 3 4
/*
 Exemplo 10. Original em pikchr.org e fossil-scm.org
 */         
        arrow "source" "code"
LA:     box "lexical" "analyzer"
        arrow "tokens" above
P:      box "parser"
        arrow "intermediate" "code" wid 200%
Sem:    box "semantic" "checker"
        arrow
        arrow <-> up from top of LA
LC:     box "lexical" "corrector"
        arrow <-> up from top of P
Syn:    box "syntactic" "corrector"
        arrow up
DMP:    box "diagnostic" "message" "printer"
        arrow <-> right  from east of DMP
ST:     box "symbol" "table"
        arrow from LC.ne to DMP.sw
        arrow from Sem.nw to DMP.se
        arrow <-> from Sem.top to ST.bot
source code lexical analyzer tokens parser intermediate code semantic checker lexical corrector syntactic corrector diagnostic message printer symbol table
/*
 Exemplo 11. Original em pikchr.org e fossil-scm.org
 */
          filewid *= 1.2
Src:      file "pikchr.y"; move
LemonSrc: file "lemon.c"; move
Lempar:   file "lempar.c"; move
          arrow down from LemonSrc.s
CC1:      oval "C-Compiler" ht 50%
          arrow " generates" ljust above
Lemon:    oval "lemon" ht 50%
          arrow from Src chop down until even with CC1 \ 
            then to Lemon.nw rad 20px
         "Pikchr source " rjust "code input " rjust \ 
            at 2nd vertex of previous
          arrow from Lempar chop down until even with CC1 \ 
            then to Lemon.ne rad 20px
          " parser template" ljust " resource file" ljust \ 
            at 2nd vertex of previous
PikSrc:   file "pikchr.c" with .n at lineht below Lemon.s
          arrow from Lemon to PikSrc chop
          arrow down from PikSrc.s
CC2:      oval "C-Compiler" ht 50%
          arrow
Out:      file "pikchr.o" "or" "pikchr.exe" wid 110%  
pikchr.y lemon.c lempar.c C-Compiler  generates lemon Pikchr source  code input   parser template  resource file pikchr.c C-Compiler pikchr.o or pikchr.exe
Sobre o Pikchr

Pikchr foi criado por D. Richard Hipp drh@sqlite.org (Zero-Clause BSD license, Copyright (C) 2020-09-01).

PIKCHR (pronunciado como "picture") é principalmente compatível com versões anteriores do legacy--PIC, embora alguns recursos do PIC tenham sido removidos (por exemplo, o comando sh foi removido por segurança) e muitos aprimoramentos foram adicionados.

Secretaria Executiva de Monitoramento

Secretário

Diogo Bezerra

diogo.bezerra@sepe.pe.gov.br

Secretário Executivo de Monitoramento

André Leite

andre.leite@sepe.pe.gov.br

Superintendente Técnico

Hortênsia Oliveira

hortensia.nunes@sepe.pe.gov.br

Gerente Geral de Monitoramento

Arissa Andrade

arissa.andrade@sepe.pe.gov.br

Assessor Especial

Rafael Zimmerle

rafael.zimmerle@sepe.pe.gov.br

Assessor Especial

Carlos Amorim

carlos.andrade@sepe.pe.gov.br

S E P E