Stwórz proste narzędzie do komentowania

14

Wyzwanie:

Niektóre ascii-art są trudne do zrobienia, ale ułatwiają czytanie komentarzy do kodu, szczególnie gdy kod jest gęsty. Wyzwanie polega na stworzeniu prostego narzędzia, które zamienia komentarze w proste ascii-art za pomocą strzałek. Komentarze do modyfikacji są rozdzielone pustymi komentarzami.

Na przykład, załóżmy, że składnia komentarza Haskell przekształca to:

--
-- Here's a thing
-- Here's another thing
-- The most important thing
-- *    *     *
--
f x=x+1*x*1*1*0

Do tego:

-- /------------< Here's a thing
-- |    /-------< Here's another thing
-- |    |     /-< The most important thing
-- |    |     |
-- v    v     v
f x=x+1*x*1*1*0

Zasady:

  • Twoja odpowiedź może być funkcją lub pełnym programem
  • Możesz wybrać język, z którym jest przeznaczony, zastępując „-” dwoma lub więcej znakami ograniczającymi komentarz w pewnym języku
  • Jeśli używasz innego formatu komentarza, który wymaga początkowych i końcowych ograniczników, każda linia przeformatowanych sekcji musi być poprawnym komentarzem
  • Sekcje, które należy sformatować, są oznaczone pustym komentarzem „\ n - \ n”
  • Oprócz dodawania nowych wierszy program nie może zmieniać żadnych danych wejściowych poza sekcjami ograniczonymi
  • Komentarz wypełniony dowolną liczbą spacji może pojawić się bezpośrednio przed odpowiednio sformatowaną sekcją wyniku
  • Standardowe luki są niedozwolone

Dodatkowe przykłady:

(input)
--
--
(output)
nothing


(input)
[Code Here]
--
-- important
--    *
--
(output)
[Code Here]
--    /-< important
--    |
--    v


(input)
--
-- Do
-- Re
-- Mi
-- Fa
-- So
-- *****
--
(output)
-- /-----< Do
-- |/----< Re
-- ||/---< Mi
-- |||/--< Fa
-- ||||/-< So
-- |||||
-- vvvvv

Punktacja:

  • Wygrywa najmniej bajtów
  • Zgłoszenia bez wyjaśnień lub nietrywialne przykładowe dane wejściowe / wyjściowe nie będą brane pod uwagę (chociaż pozostawiam okres karencji, aby dać czas na dodanie takich informacji)
Michael Klein
źródło
2
Co się stanie, jeśli tylko jeden znak będzie potrzebny do rozgraniczenia komentarza?
Adám
Dopóki jest to poprawny komentarz w języku, jest w porządku
Michael Klein
Możemy założyć, że każda sekcja komentarza, która podlega przeformatowaniu, będzie zawierała dokładnie jedną linię gwiazdek znacznika pozycji, prawda? Czy ta linia będzie zawsze ostatnia?
manatwork
Tak, dokładnie jeden i zawsze ostatni (komentarz przed ogranicznikiem końca)
Michael Klein
Liczba gwiazdek będzie równa liczbie poprzedzających wierszy w tej sekcji, prawda?
manatwork

Odpowiedzi:

4

Ruby, 160 znaków

->c{c.gsub(/^--$(.+?)^--$/m){*t,a=$&.lines[1..-2]
a&&a.chop!&&(t.map{|l|a[?*]=?/
l[0,2]=a.gsub(/(?<=\/).*/){?-*$&.size}+'-<'
a[?/]=?|
l}<<a+$/+a.tr(?|,?v))*''}}

Przykładowy przebieg:

2.1.5 :001 > puts ->c{c.gsub(/^--$(.+?)^--$/m){*t,a=$&.lines[1..-2];a&&a.chop!&&(t.map{|l|a[?*]=?/;l[0,2]=a.gsub(/(?<=\/).*/){?-*$&.size}+'-<';a[?/]=?|;l}<<a+$/+a.tr(?|,?v))*''}}["
2.1.5 :002"> --
2.1.5 :003"> -- Here's a thing
2.1.5 :004"> -- Here's another thing
2.1.5 :005"> -- The most important thing
2.1.5 :006"> -- *    *     *
2.1.5 :007"> --
2.1.5 :008"> f x=x+1*x*1*1*0
2.1.5 :009"> "]

-- /------------< Here's a thing
-- |    /-------< Here's another thing
-- |    |     /-< The most important thing
-- |    |     |
-- v    v     v
f x=x+1*x*1*1*0
 => nil 

Krótki opis:

.lines splits the section to array items ─────────╮
                                                  ▽

.gsub extracts ⎧   --                             0         
these sections ⎪   -- Here's a thing              1   t[0]   
for processing ⎨   -- Here's another thing        2   t[1]   
and replaces   ⎪   -- The most important thing    ⋮   t[2]   
them with the  ⎪   -- *    *     *               -2   a      
pretty version ⎩   --                            -1          
rest untouched —   f x=x+1*x*1*1*0
                                                      △
only the needed lines get into variables ─────────────╯



a = "-- *    *     *" + "-<"           inside .gsub's block
        ↓↓                             the first 2 characters
t[0] = "-- Here's a thing"             of t's each item are
t[1] = "-- Here's another thing"       replaced with a's value
t[2] = "-- The most important thing"   and the the separator



not only t's items are transformed inside .gsub's block,
but a's value also gets changed in multiple small steps

                       change a's value    change the value    change a's value
   a's initial value   before insertion   being inserted now   after insertion
   ╭───────────────╮   ╭───────────────╮   ╭───────────────╮   ╭───────────────╮

0  "-- *    *     *" → "-- /    *     *" → "-- /-----------" → "-- |    *     *"
1  "-- |    *     *" → "-- |    /     *" → "-- |    /------" → "-- |    |     *"
2  "-- |    |     *" → "-- |    |     /" → "-- |    |     /" → "-- |    |     |"

                       ╰───────────────╯   ╰───────────────╯   ╰───────────────╯
                      change first * to /  change everything  change first / to |
                                          after / with string
                                          of - of same length
człowiek w pracy
źródło
5

JavaScript (ES6), 418 , 237 , 233 , 236 bajtów

f=(s)=>(d='\n//',s.split(d+'\n').map((x,y)=>y%2?'//'+(l=x.slice(2).split(d),t=l.pop().split('*'),l.map((i,j)=>t.map((k,m)=>m==j?k+'/':m<j?k+'|':k.replace(/ /g,'-')+'-').join('')+'<'+i).join(d)+d+t.join('|')+d+t.join('v')):x).join('\n'))

Uff, to moje pierwsze zgłoszenie do CG. Wydaje mi się, że zajęło to coś zupełnie innego niż Washington Guedes. Skończył 54 bajty krótsze niż jego pierwsze przejście. Ręczne rozwiązywanie tego wszystkiego było wyczerpujące. Żałuję, że nie jestem jeszcze w stanie wyeliminować pętli while, co pozwoliłoby mi również ograniczyć zwrot.

Całkowicie przepisz, czerpiąc częściowo inspirację z kilku innych odpowiedzi. Muszę zamknąć wszystko na mapach, dzięki czemu powrót jest znacznie lepszy. Fragment kodu zawiera skomentowaną wersję.

Wziął jeszcze kilka bajtów i sprawił, że przykład działał na sobie. (Będziesz potrzebował większego monitora.) :)

Zapomniałem całej litery w specyfikacji! Na szczęście dodanie wiodącego „<” było drobną, trywialną poprawką.

Emmett R.
źródło
3

Python 2, 299 bajtów

Oczekuje końca nowej linii w danych wejściowych

i=input().split('--\n')
a=0
for j in i:
 a+=1
 if a%2:print j,;continue
 if''==j:continue
 l=j.split('\n');n=l[-2];r=l[:-2];R=[n.replace('*','v'),n.replace('*','|')];L=R[1]
 for x in range(len(l)-2)[::-1]:L=L[:L.rfind('|')]+'/';R+=[L.ljust(n.rfind('*')+2,'-')+'< '+r[x][3:]]
 print'\n'.join(R[::-1])

Wyjaśnienie / przykład

Wejście:

[Code Here]
--
-- important
--    *
--

Dzieli dane wejściowe według --\n. Co drugi ciąg jest ograniczonym blokiem komentarzy.

['[Code Here]\n',
'-- important\n-- stuff\n--    *  *\n',
'']

Przebiega przez każdy ciąg. Jeśli ciąg nie jest komentarzem, po prostu drukuje ciąg. Inaczej:

Dzieli każdą linię w bloku komentarza.

['-- important', '-- stuff', '--    *  *', '']

Tworzy dolne dwie linie, zastępując linie *s przy pomocy vi |.

['--    v  v', '--    |  |']

Dla każdego wiersza komentarzy (do tyłu) usuń kolumnę z prawej strony, dodaj /, -uzupełnij i dodaj komentarz.

'--    |  /'
'--    /'
'--    /----< important'

Drukuj wszystko

--    /----< important
--    |  /-< stuff
--    |  |
--    v  v

Mniej golfa:

i=input().split('--\n')
a=0
for j in i:
 a+=1
 if a%2:print j,;continue # Not commment
 if''==j:continue # Empty comment
 l=j.split('\n') # Split comment into lines
 r=l[:-2]
 # Replace line of *s with v and | respectively
 R=[l[-2].replace('*','v'),l[-2].replace('*','|')]
 L=R[1][3:] # line of |
 for x in range(len(l)-2)[::-1]: # For each comment line
  L=L[:L.rfind('|')]+'/' #Remove rightmost column
  # Add a line with '-- ',columns, and comment
  R+=['-- '+L.ljust(n.rfind('*')-1,'-')+'< '+r[x][3:]]
 print'\n'.join(R[::-1]) #Print all comment lines
TFeld
źródło
1

JavaScript (ES6), 253

Jako funkcja anonimowa, z kodem do sformatowania jako parametrem ciągu i zwracającym sformatowany kod.

Notatki

  1. Para komentarzy znaczników musi zawierać odpowiedni tekst (wiersze komentarza, a następnie gwiazdki)
  2. ... lub para nie może zawierać żadnych elementów (dodatkowy przykład 1)
t=>(t=t.split`
`,t.map((r,i)=>r=='--'?(c++&&l.map((r,j)=>(p+=q[j],z+=~q[j].length,t[i-n+j]=p+`/${'-'.repeat(z+1)}<`+r.slice(3),p+=`|`),q=l.pop(c=p=``)||p,z=q.length,q=q.split`*`,t[i]=p+q.join`v`,t[i-1]=p+q.join`|`),l=[]):n=l.push(r),c=0,l=[]),t.join`
`)

Mniej golfa

f=t=>{
  t = t.split`\n`; // string to array of lines
  l = []; // special coment text
  c = 0; // counter of marker comment '--'
  t.forEach((r,i)=>{ // for each line of t - r: current line, i: index
    if (r == '--') // if marker comment
    {
       ++ c; // increment marker counter
       if (c > 1) // this is a closing marker
       {
          c = 0; // reset marker counter
          if (n > 0) // n is the length of array l
             q = l.pop(); // get last line from l, have to be the star line
          else
             q = ''; // no text comment, no star line 
          p = '';  // prefix for drawing the tree
          z = q.length; // length of star line, used to draw the tree horiz lines
          q = q.split('*'); // split to get star count and position
          // each element in q is the spaces between stars
          // modifiy the current and previous text line 
          t[i] = p + q.join`v`; // current row was '--', becomes the V line
          t[i-1] = p + q.join`|`; // previous row was the star line, becomes the last tree line
          l.forEach((r,j)=>{ // for each line in l, r: current line, j: index
             // each line in tree is: prefix("-- |  |"...) + ... "---< " + text
             p = p + q[j]; // adjust prefix
             z = z - q[j].length - 1 // adjust length of '---'
             // modify text in t
             t[i-n+j] = p // prefix
                + '/' + '-'.repeat(z+1) + '<'  // horiz line and <
                + r.slice(3); // text, removed '-- '
             p = p + '|'; // add vertical bar to prefix
          });
       } // end if closing comment
       l = []; // reset l
    }  
    else // not a special comment marker
       n = l.push(r) // add current line to l, set n to array size
  });
  return t.join`\n` // join to a single string
}

Test

edc65
źródło
To pomija drugi blok komentarza dla mnie na chrome 47 bez błędów. Poza tym, cholera, nie widziałem wcześniej, że można użyć dowolnej składni komentarza w dowolnym języku .
Emmett R.
Masz rację. @EmmettR. dzięki. Spróbuję to naprawić
edc65