Faça uma ferramenta simples de comentário bonito


14

Desafio:

Algumas obras de arte são difíceis de fazer, mas tornam os comentários de código mais fáceis de ler, especialmente quando o código é denso. O desafio é criar uma ferramenta simples que converta comentários em arte ASCII simples com setas. Os comentários a serem modificados são delimitados por comentários vazios.

Por exemplo, supondo a sintaxe do comentário Haskell, converta isso:

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

Para isso:

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

Regras:

  • Sua resposta pode ser uma função ou um programa completo
  • Você pode escolher o idioma para o qual trabalha, substituindo o "-" por dois ou mais caracteres que delimitam um comentário em algum idioma
  • Se estiver usando outro formato de comentário que exija delimitadores iniciais e finais, cada linha das seções reformatadas deverá ser um comentário adequado
  • As seções a serem reformatadas são delimitadas pelo comentário vazio "\ n - \ n"
  • Além de adicionar novas linhas, o programa não deve alterar nenhuma entrada, exceto as seções delimitadas
  • Um comentário preenchido com um número arbitrário de espaços pode vir imediatamente antes de uma seção de saída adequadamente formatada
  • As brechas padrão não são permitidas

Exemplos adicionais:

(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

Pontuação:

  • Menos bytes ganhos
  • Submissões sem explicações ou exemplos não triviais de entrada / saída não serão consideradas (embora eu deixe um período de carência para permitir tempo para adicioná-las)

2
E se apenas um caractere for necessário para delimitar um comentário?
Adám

Desde que seja um comentário válido no idioma, tudo bem
Michael Klein

Podemos assumir que cada seção de comentário sujeita a reformatação conterá exatamente uma linha de asteriscos de marcador de posição, certo? Essa linha será sempre a última?
manatwork

Sim, exatamente um e sempre passado (comentário antes delimitador final)
Michael Klein

E a quantidade de asteriscos será igual ao número de linhas anteriores nessa seção, certo?
manatwork

Respostas:


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

Exemplo de execução:

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 

Descrição breve:

.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

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

Ufa, esta é minha primeira submissão no CG. Tomou, acho, uma abordagem totalmente diferente de Washington Guedes. Acabou 54 bytes mais curto que seu primeiro passe. Minimizar tudo isso à mão era cansativo. Meu único arrependimento é não conseguir eliminar o loop while ainda, o que também me permitiria reduzir o retorno.

Reescrita total, inspirando-se parcialmente em algumas das outras respostas. Eu consegui fechar a coisa toda nos mapas, tornando o retorno muito melhor. O trecho de código contém a versão comentada.

Tirou mais alguns bytes e fez o exemplo operar em si mesmo. (Você vai precisar de um monitor maior.) :)

Esqueceu uma carta inteira na especificação! Felizmente, adicionar o '<' principal foi uma correção minúscula e trivial.


3

Python 2, 299 bytes

Espera uma nova linha à direita na 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])

Explicação / Exemplo

Entrada:

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

Divide a entrada por --\n. Cada segunda sequência é um bloco de comentários delimitado.

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

Percorre cada sequência. Se a sequência não for um comentário, apenas imprima a sequência. De outra forma:

Divide cada linha no bloco de comentários.

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

Faz as duas linhas inferiores substituindo as linhas de *s por ve |.

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

Para cada linha de comentários (para trás), remova a coluna mais à direita, adicione /, cole com -e adicione comentário.

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

Imprimir tudo

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

Menos golfe:

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

1

JavaScript (ES6), 253

Como uma função anônima, com o código para formatar como um parâmetro de sequência e retornando o código formatado.

Notas

  1. O par de comentários do marcador deve incluir o texto correto (linhas de comentário e estrelas)
  2. ... ou o par não deve incluir nada (exemplo 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 golfe

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
}

Teste


Isso perde o segundo bloco de comentários para mim no chrome 47 sem erros. Além disso, porcaria, eu não vi antes que você pudesse usar qualquer sintaxe de comentário em qualquer idioma .
Emmett R.

Sim, você está certo. @EmmettR. obrigado. Vou tentar consertá-lo
edc65 15/01
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.