Haz una herramienta simple para hacer comentarios bonitos

14

Desafío:

Es difícil hacer algunos ascii-art, pero hace que los comentarios de código sean más fáciles de leer, especialmente cuando el código es denso. El desafío es hacer una herramienta simple que convierta los comentarios en arte ascii simple con flechas. Los comentarios a modificar están delimitados por comentarios vacíos.

Por ejemplo, suponiendo que la sintaxis del comentario de Haskell, convierta esto:

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

A esto:

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

Reglas:

  • Su respuesta puede ser una función o un programa completo
  • Puede elegir el idioma con el que está hecho para trabajar, reemplazando el "-" con dos o más caracteres que delimitan un comentario en algún idioma
  • Si usa otro formato de comentario que requiere delimitadores iniciales y finales, cada línea de las secciones reformateadas debe ser un comentario apropiado
  • Las secciones a reformatear están delimitadas por el comentario vacío "\ n - \ n"
  • Además de agregar nuevas líneas, el programa no debe cambiar ninguna entrada excepto las secciones delimitadas
  • Un comentario lleno de un número arbitrario de espacios puede aparecer inmediatamente antes de una sección de salida con el formato correcto
  • Las lagunas estándar no están permitidas

Ejemplos adicionales:

(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

Puntuación:

  • Pocos bytes ganan
  • No se considerarán las presentaciones sin explicaciones o entradas / salidas de ejemplo no triviales (aunque dejaré un período de gracia para permitir tiempo para agregarlas)
Michael Klein
fuente
2
¿Qué sucede si solo se necesita un personaje para delimitar un comentario?
Adám
Mientras sea un comentario válido en el idioma, está bien
Michael Klein
Podemos suponer que cada sección de comentarios que está sujeta a reformateo contendrá exactamente una línea de asteriscos de marcador de posición, ¿verdad? ¿Será esa línea siempre la última?
manatwork
Sí, exactamente uno y siempre el último (comentario antes del delimitador final)
Michael Klein
Y la cantidad de asteriscos será igual al número de líneas anteriores en esa sección, ¿verdad?
manatwork

Respuestas:

4

Ruby, 160 caracteres.

->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))*''}}

Ejecución de muestra:

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 

Breve descripción:

.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
hombre trabajando
fuente
5

JavaScript (ES6), 418 , 237 , 233 , 236 bytes

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'))

Menos mal, esta es mi primera presentación sobre CG. Tomó, creo, una táctica totalmente diferente de Washington Guedes. Terminó 54 bytes más corto que su primer pase. Minificar todo esto a mano fue agotador. Lo único que lamento es no haber podido eliminar el ciclo while todavía, lo que también me permitiría reducir el retorno.

Reescritura total, tomando inspiración parcial de algunas de las otras respuestas. Tengo que cerrar todo en mapas, haciendo que regresar sea mucho mejor. El fragmento de código contiene la versión comentada.

Tomó unos pocos bytes más e hizo que el ejemplo funcionara solo. (Necesitarás un monitor más grande) :)

Olvidé una carta completa en la especificación! Afortunadamente, agregar el '<' principal fue una pequeña y trivial solución.

Emmett R.
fuente
3

Python 2, 299 bytes

Espera una nueva línea final en la entrada

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])

Explicación / Ejemplo

Entrada:

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

Divide la entrada por --\n. Cada segunda cadena es un bloque de comentarios delimitado.

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

Corre a través de cada cadena. Si la cadena no es un comentario, simplemente imprime la cadena. De otra manera:

Divide cada línea en el bloque de comentarios.

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

Hace las dos líneas inferiores reemplazando las líneas de *s con vy |.

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

Para cada línea de comentarios (hacia atrás) elimine la columna de la derecha, agregue /, rellene -y agregue comentarios.

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

Imprime todo

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

Menos golfizado:

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
fuente
1

JavaScript (ES6), 253

Como una función anónima, con el código para formatear como un parámetro de cadena y devolver el código formateado.

Notas

  1. El par de comentarios de marcador debe incluir el texto correcto (líneas de comentario, luego estrellas)
  2. ... o el par no debe incluir nada (ejemplo adicional 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`
`)

Menos golf

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
}

Prueba

edc65
fuente
Esto pierde el segundo bloque de comentarios para mí en Chrome 47 sin errores. Además, mierda, no vi antes que pudieras usar cualquier sintaxis de comentarios con cualquier idioma .
Emmett R.
Uh, sí, tienes razón. @EmmettR. Gracias. Trataré de arreglarlo
edc65