Faire un simple outil de joli commentaire

14

Défi:

Certains ascii-art sont difficiles à réaliser, mais facilitent la lecture des commentaires de code, surtout lorsque le code est dense. Le défi est de créer un outil simple qui convertit les commentaires en simple ascii-art avec des flèches. Les commentaires à modifier sont délimités par des commentaires vides.

Par exemple, en supposant la syntaxe de commentaire Haskell, convertissez ceci:

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

Pour ça:

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

Règles:

  • Votre réponse peut être une fonction ou un programme complet
  • Vous pouvez choisir la langue avec laquelle il est conçu pour fonctionner, en remplaçant le "-" par deux ou plusieurs caractères qui délimitent un commentaire dans une langue
  • Si vous utilisez un autre format de commentaire qui nécessite des délimiteurs de début et de fin, chaque ligne des sections reformatées doit être un commentaire approprié
  • Les sections à reformater sont délimitées par le commentaire vide "\ n - \ n"
  • Outre l'ajout de nouvelles lignes, le programme ne doit modifier aucune des entrées à l'exception des sections délimitées
  • Un commentaire rempli d'un nombre arbitraire d'espaces peut apparaître juste avant une section de sortie correctement formatée
  • Les failles standard sont interdites

Exemples supplémentaires:

(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

Notation:

  • Le moins d'octets gagne
  • Les soumissions sans explications ou exemple d'entrées / sorties non triviales ne seront pas prises en compte (bien que je laisse un délai de grâce pour laisser le temps de les ajouter)
Michael Klein
la source
2
Que faire si un seul caractère est nécessaire pour délimiter un commentaire?
Adám
Tant que c'est un commentaire valide dans la langue, ça va
Michael Klein
Nous pouvons supposer que chaque section de commentaire soumise à un reformatage contiendra exactement une ligne d'astérisques de marqueur de position, n'est-ce pas? Cette ligne sera-t-elle toujours la dernière?
manatwork
Ouaip, exactement un et toujours dernier (commentaire avant le délimiteur de fin)
Michael Klein
Et le nombre d'astérisques sera égal au nombre de lignes précédentes dans cette section, non?
manatwork du

Réponses:

4

Ruby, 160 caractères

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

Exemple d'exécution:

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 

Brève description:

.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
homme au travail
la source
5

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

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

Ouf, ceci est ma première soumission sur CG. J'ai pris, je pense, une approche totalement différente de Washington Guedes. A fini 54 octets de moins que sa première passe. Réduire tout cela à la main était exténuant. Mon seul regret est de ne pas avoir pu éliminer la boucle while, ce qui me permettrait également de réduire le retour.

Réécriture totale, en s'inspirant partiellement de quelques autres réponses. J'ai pu fermer le tout dans les cartes, ce qui rend le retour bien meilleur. L'extrait de code contient la version commentée.

A pris quelques octets de plus et a fait fonctionner l'exemple sur lui-même. (Tu vas avoir besoin d'un moniteur plus grand.) :)

Vous avez oublié une lettre entière dans la spécification! Heureusement, l'ajout du premier «<» était une solution minuscule et triviale.

Emmett R.
la source
3

Python 2, 299 octets

Attend une nouvelle ligne de fin dans l'entrée

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

Explication / exemple

Contribution:

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

Divise l'entrée par --\n. Chaque seconde chaîne est un bloc de commentaire délimité.

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

Exécute chaque chaîne. Si la chaîne n'est pas un commentaire, imprime simplement la chaîne. Autrement:

Fractionne chaque ligne du bloc de commentaires.

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

Rend les deux lignes du bas en remplaçant les lignes de *s par vet |.

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

Pour chaque ligne de commentaires (en arrière), supprimez la colonne la plus à droite, ajoutez /, complétez avec -et ajoutez un commentaire.

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

Imprimer tout

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

Moins golfé:

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
la source
1

JavaScript (ES6), 253

En tant que fonction anonyme, avec le code à formater comme paramètre de chaîne et renvoyant le code formaté.

Remarques

  1. La paire de commentaires marqueurs doit contenir le bon texte (lignes de commentaires, puis étoiles)
  2. ... ou la paire ne doit rien contenir (exemple supplémentaire 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`
`)

Moins 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
}

Tester

edc65
la source
Cela manque le deuxième bloc de commentaires pour moi sur chrome 47 sans erreur. Aussi, merde, je n'ai pas vu auparavant que vous pouviez utiliser n'importe quelle syntaxe de commentaire avec n'importe quelle langue .
Emmett R.
Euh, oui, vous avez raison. @EmmettR. Merci. Je vais essayer de le réparer
edc65