Interfaces de usuário Ascii

18

Nesse desafio, renderizamos interfaces de usuário Ascii.

+----------------------+
|+-----------++-------+|
||<- Previous||Next ->||
|+-----------++-------+|
|== The title ==       |
|                      |
|Lorem ipsum dolor     |
|sit amet...           |
|+--------------+      |
||Post a comment|      |
|+--------------+      |
|+-----------------+   |
||User X commented:|   |
||                 |   |
||This is amazing! |   |
|+-----------------+   |
|+-----------------+   |
||User Y commented:|   |
||                 |   |
||lol              |   |
|+-----------------+   |
+----------------------+

Cada desenho como este é feito de um elemento , que pode conter subelementos. Os possíveis elementos estão listados abaixo:

  1. Elemento de texto. Contém uma ou mais linhas de texto.
  2. Elemento de caixa. Contém um subelemento cercado por bordas. As bordas têm +s nos cantos -es e |nas bordas.
  3. Lista horizontal. Contém um ou mais elementos alinhados horizontalmente.
  4. Lista vertical. Contém um ou mais elementos alinhados um sobre o outro verticalmente e à esquerda horizontalmente.

Todo elemento é um retângulo.

Cada elemento, além de seu conteúdo, possui uma propriedade chamada linha de base . A linha de base é usada para alinhar os elementos verticalmente: todos os elementos de uma lista horizontal são alinhados de modo que suas linhas de base estejam na mesma linha. No exemplo abaixo, a linha de base contém caracteres aeg. As linhas de base dos três elementos de caixa são (0-indexada) 1, 3e 2.

   +-+   
   |c|+-+
+-+|d||f|
|a||e||g|
|b|+-+|h|
+-+   +-+

As linhas de base são determinadas com as seguintes regras:

  1. Para elementos de texto, a primeira linha do texto é a linha de base, ou seja. 0.
  2. Para elementos de caixa, a linha de base é 1 + a linha de base do subelemento.
  3. Para listas horizontais, a linha de base é a linha de base máxima na lista ( 3no exemplo acima).
  4. Para listas verticais, a linha de base é a linha de base de um elemento, que deve ser especificada na entrada.

Entrada

A entrada é uma especificação de uma interface em algum formato (por exemplo, lists, json). As entradas de exemplo têm o seguinte formato:

  1. Um elemento de string é uma string: "..."
  2. Um elemento de caixa é uma lista que é o primeiro elemento "b":["b", subelement]
  3. Uma lista horizontal é uma lista que é o primeiro elemento "h":["h", items...]
  4. Uma lista vertical é uma lista que é o primeiro elemento "v"e o segundo elemento é o número (indexado 0) do elemento que é a linha de base:["v", n, items...]

Resultado

A saída deve conter os elementos alinhados usando as regras especificadas acima. A saída pode ser stdout, uma lista de strings ou qualquer outra coisa significativa.

Pontuação

Isso é , as regras usuais se aplicam.

Casos de teste

1

["b", ["v", 0, ["h", ["b", "<- Previous"], ["b", "Next ->"]], "== The title ==\n\nLorem ipsum dolor\nsit amet...", ["b", "Post a comment"], ["b", "User X commented:\n\nThis is amazing!"], ["b", "User Y commented:\n\nlol"]]]

+----------------------+
|+-----------++-------+|
||<- Previous||Next ->||
|+-----------++-------+|
|== The title ==       |
|                      |
|Lorem ipsum dolor     |
|sit amet...           |
|+--------------+      |
||Post a comment|      |
|+--------------+      |
|+-----------------+   |
||User X commented:|   |
||                 |   |
||This is amazing! |   |
|+-----------------+   |
|+-----------------+   |
||User Y commented:|   |
||                 |   |
||lol              |   |
|+-----------------+   |
+----------------------+

2

["h", ["b", ["v", 0, "a", "b"]], ["b", ["v", 2, "c", "d", "e"]], ["b", ["v", 1, "f", "g", "h"]]]

   +-+   
   |c|+-+
+-+|d||f|
|a||e||g|
|b|+-+|h|
+-+   +-+

3

["h", ["b", ["v", 0, ["b", ["h", "a\nb", "c"]], "d", "e", ["h", ["h", "f"], ["b", ["h", "g"]], "h"]]], ["b", "ijk\nl\nmn\no"], ["v", 2, ["b", "pqrst"], ["b", "uv\nw"], ["b", "x"]], ["b", ["b", ["b", "yz"]]]]

            +-----+        
            |pqrst|        
            +-----+        
            +--+           
            |uv|           
            |w |   +------+
+-----+     +--+   |+----+|
|+--+ |+---++-+    ||+--+||
||ac| ||ijk||x|    |||yz|||
||b | ||l  |+-+    ||+--+||
|+--+ ||mn |       |+----+|
|d    ||o  |       +------+
|e    |+---+               
| +-+ |                    
|f|g|h|                    
| +-+ |                    
+-----+                    

4

["h", "a * b = ", ["v", 0, "a + a + ... + a", "\\_____________/", "    b times"]]

a * b = a + a + ... + a
        \_____________/
            b times    
fergusq
fonte
2
Doce Jesus ... São geocidades mais uma vez.
Magic Octopus Urn
Não tenho muita certeza de como a linha de base funciona. Você poderia explicar melhor?
Stan Strum
@StanStrum A linha de base é usada para alinhar os itens em uma lista horizontal verticalmente. As linhas de base dos itens devem corresponder, ou seja. todos devem ter a mesma linha física. Por exemplo, no exemplo swcond, a primeira caixa foi movida para baixo, de modo que a letra aesteja na mesma linha que e, pois ambas estão na linha de base de suas caixas. Não tenho certeza absoluta se "linha de base" é a palavra correta para isso, sei apenas que ela é usada no campo da tipografia para uma finalidade semelhante.
Fergusq
@fergusq Na primeira cláusula: "Para elementos de texto, a primeira linha de texto é a linha de base, ou seja, 0.", isso significa que as outras "linhas de base" estão mudando o texto?
Stan Strum
@fergusq linha de base deve ser a palavra correta, IIRC ele é usado nas descrições para flexbox CSS bem
ASCII-only

Respostas:

10

Python 3 , 721 694 693 671 661 bytes

Editar: salvou 27 bytes devido a @Arnold Palmer e @Step Hen

Editar: salvo 1 byte

Edit: salvou 22 bytes graças a @Arnold Palmer

Editar: salvou 10 bytes

Provavelmente isso poderia ser jogado bastante

L,M,R,e=len,max,range,lambda t:([list(r)+[" "]*(M(map(L,t.split("\n")))-L(r))for r in t.split("\n")],0)if str==type(t)else b(t)if"h">t[0]else h(t)if"v">t[0]else v(t);F=lambda t:"\n".join(map("".join,e(t)[0]))
def h(t):
	t=[e(r)for r in t[1:]];Z=M(s[1]for s in t);X=M(L(s[0])-s[1]for s in t)+Z;u=[[]for i in R(X)]
	for a,b in t:u=[u[j]+[Z-b<=j<L(a)+Z-b and a[j-Z+b][i]or" "for i in R(L(a[0]))]for j in R(X)]
	return u,Z
def b(t):t,b=e(t[1]);u=[["+",*"-"*L(t[0]),"+"]];return u+[["|"]+r+["|"]for r in t]+u,1+b
def v(t):w=[e(r)for r in t[2:]];return[a[i]+[" "]*(M(L(a[0])for a,d in w)-L(a[i]))for a,c in w for i in R(L(a))],sum(L(x[0])for x in w[:t[1]])+w[t[1]][1]

Experimente online

Halvard Hummel
fonte
Você também pode mover todas as definições e P,L,M,R,K=[" "],len,max,range,mappara o topo do programa (variáveis ​​na parte superior) e para fora de F. Fazendo isso, você pode reduzi-lo a pelo menos 711 bytes. (Link TIO muito grande para postar).
Arnold Palmer
@ StapHen Agora não, eu corrigi o problema. :-)
Erik the Outgolfer
Até 671 . Tinha que usar tinyurl, pois o link do TIO era muito longo. Reescrevi muitos de seus maps, pois eles poderiam ser substituídos por coisas normais de compreensão de lista. Como consegui cortar tantos maps, também removi a Kvariável, pois estava custando 2 bytes.
Arnold Palmer
Bom trabalho. Você ganha a recompensa.
Oliver Ni