FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour extractor de texto de un PDF
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
extractor de texto de un PDF
Posted: Sat Jun 08, 2013 06:18 AM
He adaptado este c贸digo en C para usarlo desde Harbour:

http://www.codeproject.com/script/Content/ViewAssociatedFile.aspx?rzp=%2FKB%2Fcpp%2FExtractPDFText%2Fextractpdftext_src.zip&zep=cp%2Fpdf.cpp&obid=7056&obtid=2&ovid=1

Aqui esta mi c贸digo. No funciona con los PDFs que he probado 贸 tal vez a煤n hay alg煤n bug en el c贸digo. Aqui lo comparto por si a alguien le apetece probarlo:
Code (fw): Select all Collapse
#include "FiveWin.ch"

function Main()

   local cPDF := MemoRead( "c:\test.pdf" )
   local nStart := At( "stream", cPDF )
   local nEnd := At( "endstream", cPDF )
   local cBuf := Replicate( Chr( 0 ), ( nEnd - nStart ) * 10 )
   local cText, nResult
   local hFile

   while nStart <= Len( cPDF )
      nStart = At( "stream", cPDF )
      nEnd = At( "endstream", cPDF )
      cBuf = Replicate( Chr( 0 ), ( nEnd - nStart ) * 10 )
      cText = SubStr( cPDF, nStart + 6, nEnd - nStart )

      if Left( cText, 1 ) == Chr( 0x0d ) .and. ;
         SubStr( cText, 2, 1 ) == Chr( 0x0a )
         nStart += 2
      elseif Left( cText, 1 ) == Chr( 0x0a )
         nStart++
      endif

      if SubStr( cText, nEnd - 2, 1 ) == Chr( 0x0d ) .and. ;
         SubStr( cText, nEnd - 1, 1 ) == Chr( 0x0a )
         nEnd -= 2
      elseif SubStr( cText, nEnd - 1, 1 ) == Chr( 0x0a )
         nEnd--
      endif

      HB_ZUNCOMPRESS( SubStr( cPDF, nStart + 6, nEnd - nStart ), @cBuf, @nResult )

      cPDF = SubStr( cPDF, nEnd + Len( "endstream" ) + 1 )

      ProcessOutput( hFile := fcreate( "c:\test.out", "wb" ), cBuf )
      FClose( hFile )
      
      if ! Empty( MemoRead( "c:\test.out" ) )
         // MsgInfo( MemoRead( "c:\test.out" ), nResult )
      endif
   end

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <wtypes.h>

#define oldchar 15

float ExtractNumber(const char* search, int lastcharoffset)
{
        float flt=-1.0;
        int i = lastcharoffset;
        char buffer[oldchar+5];

        while (i>0 && search[i]==' ') i--;
        while (i>0 && (isdigit(search[i]) || search[i]=='.')) i--;
        ZeroMemory(buffer,sizeof(buffer));
        strncpy(buffer, search+i+1, lastcharoffset-i);
        if (buffer[0] && sscanf(buffer, "%f", &flt))
        {
                return flt;
        }
        return -1.0;
}
BOOL seen2(const char* search, char* recent)
{
if (    recent[oldchar-3]==search[0]
     && recent[oldchar-2]==search[1]
         && (recent[oldchar-1]==' ' || recent[oldchar-1]==0x0d ||
recent[oldchar-1]==0x0a)
         && (recent[oldchar-4]==' ' || recent[oldchar-4]==0x0d ||
recent[oldchar-4]==0x0a)
         )
        {
                return TRUE;
        }
        return FALSE;
}

#include <hbapifs.h>

static int xputc( unsigned char c, FILE * fo )
{
   static int iPos = 0;

   return hb_fsWriteAt( ( HB_FHANDLE ) fo, &c, 1, iPos++ );
}

void ProcessOutput(FILE* file, char* output, size_t len)
{
        //Are we currently inside a text object?
        BOOL intextobject = FALSE;

        //Is the next character literal (e.g. \\ to get a \ character or \( to get ( ):
        BOOL nextliteral = FALSE;

        //() Bracket nesting level. Text appears inside ()
        int rbdepth = 0;

        //Keep previous chars to get extract numbers etc.:
        char oc[oldchar];
        int j=0;
        size_t i;

        for (j=0; j<oldchar; j++) oc[j]=' ';

        for( i=0; i<len; i++)
        {
                unsigned char c = output[i];

                xputc( c, file );

                if (intextobject)
                {
                        if (rbdepth==0 && seen2("TD", oc))
                        {
                                //Positioning.
                                //See if a new line has to start or just a tab:
                                float num = ExtractNumber(oc,oldchar-5);
                                if (num>1.0)
                                {
                                        xputc(0x0d, file);
                                        xputc(0x0a, file);
                                }
                                if (num<1.0)
                                {
                                        xputc('\t', file);
                                }
                        }
                        if (rbdepth==0 && seen2("ET", oc))
                        {
                                //End of a text object, also go to a new line.
                                intextobject = FALSE;
                                xputc(0x0d, file);
                                xputc(0x0a, file);
                        }
                        else if (c=='(' && rbdepth==0 && !nextliteral)
                        {
        int num;
                                //Start outputting text!
                                rbdepth=1;
                                //See if a space or tab (>1000) is called for by looking
                                //at the number in front of (
                                num = ExtractNumber(oc,oldchar-1);
                                if (num>0)
                                {
                                        if (num>1000.0)
                                        {
                                                xputc('\t', file);
                                        }
                                        else if (num>100.0)
                                        {
                                                xputc(' ', file);
                                        }
                                }
                        }
                        else if (c==')' && rbdepth==1 && !nextliteral)
                        {
                                //Stop outputting text
                                rbdepth=0;
                        }
                        else if (rbdepth==1)
                        {
                                //Just a normal text character:
                                if (c=='\\' && !nextliteral)
                                {
                                        //Only print out next character no matter what. Do not interpret.
                                        nextliteral = TRUE;
                                }
                                else
                                {
                                        nextliteral = FALSE;
                                        if ( ((c>=' ') && (c<='~')) || ((c>=128) && (c<255)) )
                                        {
                                                xputc(c, file);
                                        }
                                }
                        }
                }
                //Store the recent characters for when we have to go back for a number:
                for (j=0; j<oldchar-1; j++) oc[j]=oc[j+1];
                oc[oldchar-1]=c;
                if (!intextobject)
                {
                        if (seen2("BT", oc))
                        {
                                //Start of a text object:
                                intextobject = TRUE;
                        }
                }
        }
}

HB_FUNC( PROCESSOUTPUT )
{
   int iLen = hb_parclen( 2 );
   // char * buffer = hb_xgrab( iLen );

   ProcessOutput( ( FILE * ) hb_parnl( 1 ), hb_parc( 2 ), iLen );
   // hb_storclen( buffer, iLen, 2 );
   // hb_xfree( buffer );
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 880
Joined: Fri Jan 12, 2007 08:35 PM
Re: extractor de texto de un PDF
Posted: Sat Jun 08, 2013 05:07 PM
Hola :-)

en el Xverce me sale lo siguiente

Code (fw): Select all Collapse
Warning W8004 - test.prg 6055: 'j' is assigned a value that is never used in function ProcessOutput
:-)


es en este pedasito

Code (fw): Select all Collapse
 //Keep previous chars to get extract numbers etc.:
聽 聽 聽 聽 char oc[oldchar];
聽 聽 聽 聽 int j=0;
聽 聽 聽 聽 size_t i;


espero se pueda lograr seria para sacar los datos de mas de 15000 archivos PDF :-)

Saluditos :-)
Que es mejor que programar? creo que nada :)
Atropellada pero aqui ando :P

I love Fivewin

s茅蕦菨晒 谉蓯 蓯蕠s菨 opun莎 菨蕠s菨
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: extractor de texto de un PDF
Posted: Sat Jun 08, 2013 06:06 PM

Aida,

j se usa aqui:

   for (j=0; j&lt;oldchar; j++) oc[j]=' ';

que compilador de C usas ?

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: extractor de texto de un PDF
Posted: Sat Jun 08, 2013 06:16 PM

Aida, Antonio creo que el compilador tiene raz贸n
o haces esto:

int j; // No se asigna el 0
...
for (j=0; j<oldchar; j++) oc[j]=' ';

o haces esto:

for ( int j=0; j<oldchar; j++) oc[j]=' ';

jaja pero las dos cosas juntas "nor" :mrgreen:

Aparezco poco por aqu铆, pero espero remediarlo pronto.

Saludos a los dos... bueno a "to er" mundo jejeje

______________________________________________________________________________

Sevilla - Andaluc铆a
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: extractor de texto de un PDF
Posted: Sat Jun 08, 2013 06:43 PM

Tienes toda la raz贸n, esa inicializaci贸n es la que sobraba :-)

Aun asi, seguimos sin saber si el c贸digo funciona o no. La funcion HB_ZUNCOMPRESS() devuelve un c贸digo de error, cero significa que los datos descomprimidos son correctos, -5 es que estan mal. En mis pruebas suele dar cero pero no aparece el texto.

A ver si entre todos lo hacemos funcionar :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 880
Joined: Fri Jan 12, 2007 08:35 PM
Re: extractor de texto de un PDF
Posted: Sat Jun 08, 2013 07:19 PM

No soy buena en c贸digo importado pero le har茅 la luchita :mrgreen:

y como queda con la correcci贸n el c贸digo ya me perd铆 :shock:

Saluditos :wink:

Que es mejor que programar? creo que nada :)
Atropellada pero aqui ando :P

I love Fivewin

s茅蕦菨晒 谉蓯 蓯蕠s菨 opun莎 菨蕠s菨
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 PM
Re: extractor de texto de un PDF
Posted: Sat Jun 08, 2013 09:57 PM
Hola

creo que el error es que se esta creando el archivo cada iteraci贸n del while, sacando la creacion/cierre del archivo de salida se avanza un poco mas

de esta forma funciona... pero el archivo de salida se guarda mal... repite las letras

Code (fw): Select all Collapse
function Main()

   local cPDF := MemoRead( "curl.pdf" )
   local nStart := At( "stream", cPDF )
   local nEnd := At( "endstream", cPDF )
   local cBuf := Replicate( Chr( 0 ), ( nEnd - nStart ) * 10 )
   local cText, nResult
   local hFile

   hFile := fcreate( "curl.out", "wb" )

   while nStart <= Len( cPDF )
      nStart = At( "stream", cPDF )
      nEnd = At( "endstream", cPDF )
      cBuf = Replicate( Chr( 0 ), ( nEnd - nStart ) * 10 )
      cText = SubStr( cPDF, nStart + 6, nEnd - nStart )

      if Left( cText, 1 ) == Chr( 0x0d ) .and. ;
         SubStr( cText, 2, 1 ) == Chr( 0x0a )
         nStart += 2
      elseif Left( cText, 1 ) == Chr( 0x0a )
         nStart++
      endif

      if SubStr( cText, nEnd - 2, 1 ) == Chr( 0x0d ) .and. ;
         SubStr( cText, nEnd - 1, 1 ) == Chr( 0x0a )
         nEnd -= 2
      elseif SubStr( cText, nEnd - 1, 1 ) == Chr( 0x0a )
         nEnd--
      endif

      HB_ZUNCOMPRESS( SubStr( cPDF, nStart + 6, nEnd - nStart ), @cBuf, @nResult )

      cPDF = SubStr( cPDF, nEnd + Len( "endstream" ) + 1 )

      ProcessOutput(hFile, cBuf )
      
      if ! Empty( MemoRead( "curl.out" ) )
        //MsgInfo( MemoRead( "curl.out" ), nResult )
      endif
   end

   FClose( hFile )

return nil
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: extractor de texto de un PDF
Posted: Sun Jun 09, 2013 07:38 AM
Daniel,

Me habia dejado una traza en el c贸digo. Ahora parece ir mucho mejor :-)

Code (fw): Select all Collapse
#include "FiveWin.ch"

function Main()

   local cPDF := MemoRead( "c:\curl.pdf" )
   local nStart := At( "stream", cPDF )
   local nEnd := At( "endstream", cPDF )
   local cBuf := Replicate( Chr( 0 ), ( nEnd - nStart ) * 10 )
   local cText, nResult
   local hFile

   if ! File( "c:\curl.out" )
      hFile = fcreate( "c:\curl.out", "wb" )
   else
      hFile = fopen( "c:\curl.out", "wb" )
   endif   

   while nStart < Len( cPDF )
      nStart = At( "stream", cPDF )
      nEnd = At( "endstream", cPDF )
      cBuf = Replicate( Chr( 0 ), ( nEnd - nStart ) * 10 )
      cText = SubStr( cPDF, nStart + 6, nEnd - nStart )

      if Left( cText, 1 ) == Chr( 0x0d ) .and. ;
         SubStr( cText, 2, 1 ) == Chr( 0x0a )
         nStart += 2
      elseif Left( cText, 1 ) == Chr( 0x0a )
         nStart++
      endif

      if SubStr( cText, nEnd - 2, 1 ) == Chr( 0x0d ) .and. ;
         SubStr( cText, nEnd - 1, 1 ) == Chr( 0x0a )
         nEnd -= 2
      elseif SubStr( cText, nEnd - 1, 1 ) == Chr( 0x0a )
         nEnd--
      endif

      HB_ZUNCOMPRESS( SubStr( cPDF, nStart + 6, nEnd - nStart ), @cBuf, @nResult )

      cPDF = SubStr( cPDF, nEnd + Len( "endstream" ) + 1 )

      ProcessOutput( hFile, cBuf )
   end

   FClose( hFile )
   MsgInfo( MemoRead( "c:\curl.out" ) )
   // FErase( "c:\curl.out" )

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <wtypes.h>

#define oldchar 15

float ExtractNumber(const char* search, int lastcharoffset)
{
        float flt=-1.0;
        int i = lastcharoffset;
        char buffer[oldchar+5];

        while (i>0 && search[i]==' ') i--;
        while (i>0 && (isdigit(search[i]) || search[i]=='.')) i--;
        ZeroMemory(buffer,sizeof(buffer));
        strncpy(buffer, search+i+1, lastcharoffset-i);
        if (buffer[0] && sscanf(buffer, "%f", &flt))
        {
                return flt;
        }
        return -1.0;
}
BOOL seen2(const char* search, char* recent)
{
if (    recent[oldchar-3]==search[0]
     && recent[oldchar-2]==search[1]
         && (recent[oldchar-1]==' ' || recent[oldchar-1]==0x0d ||
recent[oldchar-1]==0x0a)
         && (recent[oldchar-4]==' ' || recent[oldchar-4]==0x0d ||
recent[oldchar-4]==0x0a)
         )
        {
                return TRUE;
        }
        return FALSE;
}

#include <hbapifs.h>

int iPos = 0;

static int xputc( unsigned char c, FILE * fo )
{
   return hb_fsWriteAt( ( HB_FHANDLE ) fo, &c, 1, iPos++ );
}

void ProcessOutput(FILE* file, char* output, size_t len)
{
        //Are we currently inside a text object?
        BOOL intextobject = FALSE;

        //Is the next character literal (e.g. \\ to get a \ character or \( to get ( ):
        BOOL nextliteral = FALSE;

        //() Bracket nesting level. Text appears inside ()
        int rbdepth = 0;

        //Keep previous chars to get extract numbers etc.:
        char oc[oldchar];
        int j;
        size_t i;

        for (j=0; j<oldchar; j++) 
           oc[j]=' ';

        for( i=0; i<len; i++)
        {
                unsigned char c = output[i];

                if (intextobject)
                {
                        if (rbdepth==0 && seen2("TD", oc))
                        {
                                //Positioning.
                                //See if a new line has to start or just a tab:
                                float num = ExtractNumber(oc,oldchar-5);
                                if (num>1.0)
                                {
                                        xputc(0x0d, file);
                                        xputc(0x0a, file);
                                }
                                if (num<1.0)
                                {
                                        xputc('\t', file);
                                }
                        }
                        if (rbdepth==0 && seen2("ET", oc))
                        {
                                //End of a text object, also go to a new line.
                                intextobject = FALSE;
                                xputc(0x0d, file);
                                xputc(0x0a, file);
                        }
                        else if (c=='(' && rbdepth==0 && !nextliteral)
                        {
        int num;
                                //Start outputting text!
                                rbdepth=1;
                                //See if a space or tab (>1000) is called for by looking
                                //at the number in front of (
                                num = ExtractNumber(oc,oldchar-1);
                                if (num>0)
                                {
                                        if (num>1000.0)
                                        {
                                                xputc('\t', file);
                                        }
                                        else if (num>100.0)
                                        {
                                                xputc(' ', file);
                                        }
                                }
                        }
                        else if (c==')' && rbdepth==1 && !nextliteral)
                        {
                                //Stop outputting text
                                rbdepth=0;
                        }
                        else if (rbdepth==1)
                        {
                                //Just a normal text character:
                                if (c=='\\' && !nextliteral)
                                {
                                        //Only print out next character no matter what. Do not interpret.
                                        nextliteral = TRUE;
                                }
                                else
                                {
                                        nextliteral = FALSE;
                                        if ( ((c>=' ') && (c<='~')) || ((c>=128) && (c<255)) )
                                        {
                                                xputc(c, file);
                                        }
                                }
                        }
                }
                //Store the recent characters for when we have to go back for a number:
                for (j=0; j<oldchar-1; j++) oc[j]=oc[j+1];
                oc[oldchar-1]=c;
                if (!intextobject)
                {
                        if (seen2("BT", oc))
                        {
                                //Start of a text object:
                                intextobject = TRUE;
                        }
                }
        }
}

HB_FUNC( PROCESSOUTPUT )
{
   ProcessOutput( ( FILE * ) hb_parnl( 1 ), hb_parc( 2 ), hb_parclen( 2 ) );
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: extractor de texto de un PDF
Posted: Sun Jun 09, 2013 08:01 AM
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: extractor de texto de un PDF
Posted: Sun Jun 09, 2013 08:10 AM
Aida,

Parece que con esta utilidad gratuita:

http://qpdf.sourceforge.net/

puedes convertir todos tus PDFs a texto :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 880
Joined: Fri Jan 12, 2007 08:35 PM
Re: extractor de texto de un PDF
Posted: Mon Jun 10, 2013 03:23 AM

Hola

ya vi sobre ese QPDF y no le entiendo nadita :shock:

creo que si se puede en xharbour y fivewin le entender茅 mas al final y aprender茅 mas que algo externo :D

soy muy fiel a Fivewin :mrgreen:

Gracias :)

Saluditos :wink:

Que es mejor que programar? creo que nada :)
Atropellada pero aqui ando :P

I love Fivewin

s茅蕦菨晒 谉蓯 蓯蕠s菨 opun莎 菨蕠s菨
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: extractor de texto de un PDF
Posted: Mon Jun 10, 2013 07:34 AM
Aida,

A mi ya me funciona correctamente :-)

Encontr茅 que aunque el formato de compresi贸n de muchos PDFs es FlateDecode, el texto que extrae necesita una nueva conversi贸n que ya he conseguido implementar. Aqui tienes la versi贸n que funciona. Revisa el fichero que genera con extensi贸n TXT que contiene el texto del PDF:

Code (fw): Select all Collapse
#include "FiveWin.ch"

function Main()

   local oVoice := TOleAuto():New( "Sapi.SPVoice" ) 
   local cText := GetText( "c:\curl.pdf" )
   
   oVoice:Speak( "c:\curl.txt", 4 )

return nil

function GetText( cPdfFile )

   local cPDF := MemoRead( cPdfFile )
   local nStart := At( "stream", cPDF )
   local nEnd := At( "endstream", cPDF )
   local cBuf := Replicate( Chr( 0 ), ( nEnd - nStart ) * 10 )
   local cText, nResult, cTemp
   local hFile, cResult := ""
   local n := 1

   if ! File( hb_CurDrive() + ":\" + cFileNoExt( cPdfFile ) + ".out" )
      hFile = fcreate( hb_CurDrive() + ":\" + cFileNoExt( cPdfFile ) + ".out", "wb" )
   else
      hFile = fopen( hb_CurDrive() + ":\" + cFileNoExt( cPdfFile ) + ".out", "wb" )
   endif   

   while "stream" $ cPDF
      nStart = At( "stream", cPDF )
      nEnd = At( "endstream", cPDF )
      
      if nStart == 0
         cPDF = ""
         exit
      endif
         
      cBuf = Replicate( Chr( 0 ), ( nEnd - nStart ) * 10 )
      cText = SubStr( cPDF, nStart + 6, nEnd - nStart )

      if Left( cText, 1 ) == Chr( 0x0d ) .and. ;
         SubStr( cText, 2, 1 ) == Chr( 0x0a )
         nStart += 2
      elseif Left( cText, 1 ) == Chr( 0x0a )
         nStart++
      endif

      if SubStr( cText, nEnd - 2, 1 ) == Chr( 0x0d ) .and. ;
         SubStr( cText, nEnd - 1, 1 ) == Chr( 0x0a )
         nEnd -= 2
      elseif SubStr( cText, nEnd - 1, 1 ) == Chr( 0x0a )
         nEnd--
      endif

      HB_ZUNCOMPRESS( SubStr( cPDF, nStart + 6, nEnd - nStart ), @cBuf, @nResult )
      cTemp = cBuf
      while "[" $ cTemp 
         // OutputDebugString( "dentro del bucle Translate" + CRLF )
         if ! "]" $ cTemp
            exit
         endif   
         cResult += Translate( SubStr( cTemp, At( "[", cTemp ), At( "]", cTemp ) - At( "[", cTemp ) + 1 ) )
         cTemp = SubStr( cTemp, At( "]", cTemp ) + 1 )
      end   

      // OutputDebugString( Str( Len( cPDF ) ) ) 
      // OutputDebugString( If( Empty( cPDF ), " * Empty", " * not empty" ) + CRLF )
      ProcessOutput( hFile, cBuf )
      cPDF = SubStr( cPDF, nEnd + Len( "endstream" ) + 1 )
   end

   // OutputDebugString( "done" )
   FClose( hFile )
   MemoWrit( hb_CurDrive() + ":\" + cFileNoExt( cPdfFile ) + ".txt", cResult )

return cResult

function Translate( cText )

   local cCode, cResult := "" 
   local nStart, nEnd, n
   
   cText = SubStr( cText, 2, Len( cText ) - 2 )
   
   while "<" $ cText
      nStart = At( "<", cText )
      nEnd = At( ">", cText )
      cCode = SubStr( cText, nStart + 1, nEnd - nStart - 1 )
      for n = 1 to Len( cCode ) step 4
         cResult += Chr( hb_HextoNum( SubStr( cCode, n, 4 ) ) )
      next   
      if nEnd != 0
         cText = SubStr( cText, nEnd + 1 )
      else 
         cText = ""
      endif      
   end   
   
return cResult + " "     

#pragma BEGINDUMP

#include <hbapi.h>
#include <wtypes.h>

#define oldchar 15

float ExtractNumber(const char* search, int lastcharoffset)
{
        float flt=-1.0;
        int i = lastcharoffset;
        char buffer[oldchar+5];

        while (i>0 && search[i]==' ') i--;
        while (i>0 && (isdigit(search[i]) || search[i]=='.')) i--;
        ZeroMemory(buffer,sizeof(buffer));
        strncpy(buffer, search+i+1, lastcharoffset-i);
        if (buffer[0] && sscanf(buffer, "%f", &flt))
        {
                return flt;
        }
        return -1.0;
}
BOOL seen2(const char* search, char* recent)
{
if (    recent[oldchar-3]==search[0]
     && recent[oldchar-2]==search[1]
         && (recent[oldchar-1]==' ' || recent[oldchar-1]==0x0d ||
recent[oldchar-1]==0x0a)
         && (recent[oldchar-4]==' ' || recent[oldchar-4]==0x0d ||
recent[oldchar-4]==0x0a)
         )
        {
                return TRUE;
        }
        return FALSE;
}

#include <hbapifs.h>

int iPos = 0;

static int xputc( unsigned char c, FILE * fo )
{
   return hb_fsWriteAt( ( HB_FHANDLE ) fo, &c, 1, iPos++ );
}

void ProcessOutput(FILE* file, char* output, size_t len)
{
        //Are we currently inside a text object?
        BOOL intextobject = FALSE;

        //Is the next character literal (e.g. \\ to get a \ character or \( to get ( ):
        BOOL nextliteral = FALSE;

        //() Bracket nesting level. Text appears inside ()
        int rbdepth = 0;

        //Keep previous chars to get extract numbers etc.:
        char oc[oldchar];
        int j;
        size_t i;

        for (j=0; j<oldchar; j++) 
           oc[j]=' ';

        for( i=0; i<len; i++)
        {
                unsigned char c = output[i];

                if (intextobject)
                {
                        if (rbdepth==0 && seen2("TD", oc))
                        {
                                //Positioning.
                                //See if a new line has to start or just a tab:
                                float num = ExtractNumber(oc,oldchar-5);
                                if (num>1.0)
                                {
                                        xputc(0x0d, file);
                                        xputc(0x0a, file);
                                }
                                if (num<1.0)
                                {
                                        xputc('\t', file);
                                }
                        }
                        if (rbdepth==0 && seen2("ET", oc))
                        {
                                //End of a text object, also go to a new line.
                                intextobject = FALSE;
                                xputc(0x0d, file);
                                xputc(0x0a, file);
                        }
                        else if (c=='(' && rbdepth==0 && !nextliteral)
                        {
        int num;
                                //Start outputting text!
                                rbdepth=1;
                                //See if a space or tab (>1000) is called for by looking
                                //at the number in front of (
                                num = ExtractNumber(oc,oldchar-1);
                                if (num>0)
                                {
                                        if (num>1000.0)
                                        {
                                                xputc('\t', file);
                                        }
                                        else if (num>100.0)
                                        {
                                                xputc(' ', file);
                                        }
                                }
                        }
                        else if (c==')' && rbdepth==1 && !nextliteral)
                        {
                                //Stop outputting text
                                rbdepth=0;
                        }
                        else if (rbdepth==1)
                        {
                                //Just a normal text character:
                                if (c=='\\' && !nextliteral)
                                {
                                        //Only print out next character no matter what. Do not interpret.
                                        nextliteral = TRUE;
                                }
                                else
                                {
                                        nextliteral = FALSE;
                                        if ( ((c>=' ') && (c<='~')) || ((c>=128) && (c<255)) )
                                        {
                                                xputc(c, file);
                                        }
                                }
                        }
                }
                //Store the recent characters for when we have to go back for a number:
                for (j=0; j<oldchar-1; j++) oc[j]=oc[j+1];
                oc[oldchar-1]=c;
                if (!intextobject)
                {
                        if (seen2("BT", oc))
                        {
                                //Start of a text object:
                                intextobject = TRUE;
                        }
                }
        }
}

HB_FUNC( PROCESSOUTPUT )
{
   ProcessOutput( ( FILE * ) hb_parnl( 1 ), ( char * ) hb_parc( 2 ), hb_parclen( 2 ) );
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 880
Joined: Fri Jan 12, 2007 08:35 PM
Re: extractor de texto de un PDF
Posted: Mon Jun 10, 2013 05:05 PM
Super :-)

en este momento lo copio y har茅 pruebas :-)

y te comento :-)

eres mi SUPERMAN


Saluditos :-)
Que es mejor que programar? creo que nada :)
Atropellada pero aqui ando :P

I love Fivewin

s茅蕦菨晒 谉蓯 蓯蕠s菨 opun莎 菨蕠s菨
Posts: 880
Joined: Fri Jan 12, 2007 08:35 PM
Re: extractor de texto de un PDF
Posted: Mon Jun 10, 2013 05:23 PM
Me sale esto

Code (fw): Select all Collapse
Error: Unresolved external '_HB_FUN_HB_CURDRIVE' referenced


Code (fw): Select all Collapse
Error: Unresolved external '_HB_FUN_HB_HEXTONUM' referenced



les quite el HB_ ya no marca error pero el curl.txt sale en blanco sin nada :-)

sera por quitar el HB_ o me faltara alguna lib del xharbour


Saluditos :-)
Que es mejor que programar? creo que nada :)
Atropellada pero aqui ando :P

I love Fivewin

s茅蕦菨晒 谉蓯 蓯蕠s菨 opun莎 菨蕠s菨
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: extractor de texto de un PDF
Posted: Mon Jun 10, 2013 07:37 PM

Aida,

Prueba con el pdf que te envio por email

regards, saludos

Antonio Linares
www.fivetechsoft.com