Justificador de texto em 80 colunas

Publicado por Enzo de Brito Ferber (última atualização em 22/01/2013)

[ Hits: 6.300 ]

Homepage: http://www.maximasonorizacao.com.br

Download just.tar

Download 1358116595.just.tar (versão 2)




Hoje eu precisei justificar um texto em 80 colunas (como o man do Linux), mas não achei nenhum programa built-in pra fazer. Então, depois de procurar muito, achei uma thread que dizia que o emacs fazia isso.... Odeio o emacs.

Então fiz o programa pra trabalhar em conjunto com o fmt do GNU/Linux.

Fica assim:

$ fmt -w 79 arquivo | ./just

O just coloca tudo em 80 colunas, usando apenas espaços. Bem legal e resolveu meu problema. Pra ficar melhor é só colocar na ~/bin

  



Versões atualizadas deste script

Versão 2 - Enviado por Enzo de Brito Ferber em 13/01/2013

Changelog: Agora funciona normalmente com fmt -80 | just.

Adicionada apenas 1 linha na função formatline() para consertar o bug de formatação.

Quando uma linha tinha exatamente o tamanho desejado, o programa ainda assim adicionava 1 espaço a mais, fazendo com que a linha ficasse fora de formato.

if ( line[ strlen(line) - 1] != '\n' ) return line;

Download 1358116595.just.tar


Esconder código-fonte

/*
 * just.c
 *
 * Extention for 'fmt' unit command to justify the text
 * to 'n' columns
 *
 * $ fmt -w 79 file | just
 *
 *
 * Author: Enzo Ferber
 *       : [email protected]
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define LINESIZE   80
#define CUTSIZE   55

/*
 * @ insertchar (str, pos, c )
 *
 * Insert character at given string positing
 *
 * - str : pointer to the string
 * - pos : the position to insert
 * - c   : character to insert
 */
char *insertchar ( char *str, int pos, char c )
{
   register int i;
   int len = strlen(str);
   
   // open space for the new character
   for ( i = len; i >= pos; i-- )
      str[i + 1] = str[i];

   // puts new character
   str[pos] = c;

   // end of string terminator
   str[len + 1] = 0x0;

   // return
   return str;
}

/*
 * @ formatline ( line, ls )
 *
 * Format the line inserting spaces in it
 *
 * - line: pointer to the line string
 * - ls  : line size - PUT THE SAME NUMBER AS IN 'fmt' -w argument
 */
char *formatline ( char *line, int ls )
{
   register int i;
   
   /*
    *  if it's just a new line
    */
   if ( line[0] == '\n') return line;

   /*
    * format
    */
   for  ( i = 0 ; i < strlen(line); i ++)
   {
      if ( strlen(line) >= ls ) break;
      else if ( line[i] == ' ' )
         line = insertchar(line, i++, ' ' );
   }
   
   /*
    * maybe just one run didn't work...
    * run the routine to put spaces again
    *
    * i.e.: strings with low spaces number
    */
   if ( strlen(line) < ls )
      line = formatline( line, ls );
   
   return line;
}
   
int main ( void )
{
        char *line = (char *)malloc(LINESIZE * sizeof(char));

   while ( fgets(line, LINESIZE, stdin) != NULL )
   {
       printf( "%s", (strlen(line) > CUTSIZE) ? 
             formatline(line, LINESIZE) : line);
       memset(line, 0x0, LINESIZE );
   }
   
   free ( line );
   return 0;
}

Scripts recomendados

Manipulação de arquivos CSV - Estruturado

Ler string de um ficheiro

Programa para inversão de colunas

Árvore B

Mexendo com arquivos em C


  

Comentários
[1] Comentário enviado por fabio em 07/01/2013 - 14:15h

Muito bom, meus parabéns!

[2] Comentário enviado por eldermarco em 07/01/2013 - 17:55h

Pô, legal isso! Gostei!

[3] Comentário enviado por EnzoFerber em 13/01/2013 - 20:45h

Obrigado pelos comentários.

Estou melhorando o código ainda, uma nova versão foi enviada para consertar o BUG com linhas com o tamanho certo. Por isso precisa do "fmt -79", na nova versão reconhece "fmt -80" e formata tudo tranquilo. Assim que conseguir reduzir o tamanho do código envio outra versão.

[]'s

[4] Comentário enviado por foxbit3r em 22/01/2013 - 22:23h

Oi Enzo,
Adiciona a linha:

char *line = (char *)malloc(LINESIZE * sizeof(char));
if(!line) {
fprintf(stderr,"Insufficient memory available");
exit(-1);
}

[5] Comentário enviado por EnzoFerber em 24/01/2013 - 13:26h

@foxbi3r

Obrigado pela contribuição. Realmente me esqueci de fazer checagem de memória. Mas acho que um buffer tão pequeno não vai dar problema.

Quem quiser evitar dores de cabeça com escrita em memória não alocada:

char *line = malloc(...)
if ( !line ) exit ( EXIT_FAILURE );



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts