Interfejsy użytkownika Ascii

18

W tym wyzwaniu renderujemy interfejsy użytkownika Ascii.

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

Każdy taki rysunek składa się z jednego elementu , który może zawierać podelementy. Możliwe elementy są wymienione poniżej:

  1. Element tekstowy. Zawiera jeden lub więcej wierszy tekstu.
  2. Element pudełkowy. Zawiera jeden podelement otoczony granicami. Granice mają +s na rogach i -s oraz |na krawędziach.
  3. Lista pozioma. Zawiera jeden lub więcej elementów, które są wyrównane w poziomie.
  4. Lista pionowa. Zawiera jeden lub więcej elementów, które są wyrównane względem siebie w pionie i do lewej w poziomie.

Każdy element jest prostokątem.

Każdy element, oprócz swojej zawartości, ma właściwość o nazwie linia bazowa . Linia bazowa służy do wyrównywania elementów w pionie: każdy element listy poziomej jest wyrównany w taki sposób, że ich linie bazowe znajdują się w tej samej linii. W poniższym przykładzie linia bazowa zawiera znaki aeg. Linie podstawowe trzech elementów skrzynkowych są (0-indeksowane) 1, 3i 2.

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

Wartości bazowe są ustalane według następujących zasad:

  1. W przypadku elementów tekstowych pierwszy wiersz tekstu jest linią bazową, tj. 0.
  2. W przypadku elementów pudełkowych linia bazowa wynosi 1 + linia bazowa podelementu.
  3. W przypadku list poziomych linia bazowa jest maksymalną linią bazową na liście ( 3w powyższym przykładzie).
  4. W przypadku list pionowych linia bazowa jest linią bazową elementu, którą należy określić na wejściu.

Wejście

Dane wejściowe to specyfikacja interfejsu w pewnym formacie (np. Listy, json). Przykładowe dane wejściowe mają następujący format:

  1. Element ciąg jest ciągiem: "..."
  2. Element box to lista, której pierwszym elementem jest "b":["b", subelement]
  3. Lista pozioma to lista, której pierwszym elementem jest "h":["h", items...]
  4. Lista pionowa jest listą, której jest pierwszy element, "v"a drugim elementem jest (indeksowany 0) numer elementu, którego podstawa jest używana:["v", n, items...]

Wynik

Dane wyjściowe muszą zawierać elementy wyrównane przy użyciu reguł określonych powyżej. Wyjściem może być standardowe wyjście, lista ciągów znaków lub cokolwiek innego znaczącego.

Punktacja

To jest , obowiązują zwykłe zasady.

Przypadki testowe

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
źródło
2
Słodki Jezu ... To znowu geocities.
Magic Octopus Urn
Nie jestem do końca pewien, jak działa ta linia bazowa. Czy możesz to wyjaśnić?
Stan Strum,
@StanStrum Linia bazowa służy do wyrównania elementów na liście poziomej w pionie. Podstawy pozycji powinny się zgadzać, tj. wszystkie powinny być w tym samym fizycznym rzędzie. Na przykład w drugim przykładzie pierwsze pole zostało przesunięte w dół, tak aby litera znajdowała się aw tej samej linii co e, ponieważ oba znajdują się na linii podstawowej swoich pól. Nie jestem do końca pewien, czy „baseline” jest właściwym słowem do tego, wiem tylko, że jest ono używane w dziedzinie typografii do podobnego celu.
fergusq
@fergusq W pierwszej klauzuli: „W przypadku elementów tekstowych pierwszy wiersz tekstu jest linią bazową, tj. 0.”, czy oznacza to, że inne „linie bazowe” przesuwają tekst w górę?
Stan Strum
@fergusq Linia bazowa powinna być poprawnym słowem, IIRC jest również używane w opisach dla flexbox CSS
tylko ASCII

Odpowiedzi:

10

Python 3 , 721 694 693 671 661 bajtów

Edycja: Zapisano 27 bajtów dzięki @Arnold Palmer i @Step Hen

Edycja: Zapisano 1 bajt

Edytować: Zaoszczędź 22 bajty dzięki @Arnold Palmer

Edycja: Zapisano 10 bajtów

Prawdopodobnie można to trochę pograć w golfa

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]

Wypróbuj online

Halvard Hummel
źródło
Możesz także przenieść wszystkie definicje i P,L,M,R,K=[" "],len,max,range,mapna górę programu (zmienne u góry) i poza F. W ten sposób możesz sprowadzić go do co najmniej 711 bajtów. (Link TIO jest zbyt duży, aby opublikować).
Arnold Palmer,
@StepHen Już nie, naprawiłem problem. :-)
Erik the Outgolfer
Do 671 . Musiałem użyć tinyurl, ponieważ łącze TIO było zbyt długie. Przerobiłem wiele twoich, mapponieważ można je zastąpić zwykłymi listami. Ponieważ byłem w stanie przyciąć tak wiele maps, usunąłem również Kzmienną, ponieważ kosztowała 2 bajty.
Arnold Palmer,
Dobra robota. Wygrywasz nagrodę.
Oliver Ni