Italian community of Lazarus and Free Pascal

Programmazione => Lazarus e il web => Topic aperto da: 00261 - Ottobre 25, 2019, 11:55:02 am

Titolo: Creazione di output html con lazarus
Inserito da: 00261 - Ottobre 25, 2019, 11:55:02 am
Dopo essermi presentato nell’apposita sezione ed appena arrivato, sia sul forum che nel mondo Lazarus, vorrei porre la mia prima domanda: ovviamente ho cercato in giro ma non sono stato in grado di trovare risposta, quindi chiedo qui…

La domanda è questa.

Avendo un file estratto da un DB così costituito,

Codice: [Seleziona]
,,,,
Disney
,Pippo
,,Pluto
,,Paperino
,,,Paperina
,,,,Minnie
,,,Paperone
,,,Paperoga
,,Gambadilegno
,Topolino
,,Basettoni
,,Clarabella
,,Paperinik
,,,Orazio

vorrei ottenere un output come quello nella Jpg allegata ottenuto da un codice html come questo:

Codice: [Seleziona]
 
<div class="tf-tree">
  <ul>
    <li>
      <span class="tf-nc">Disney</span>
      <ul>
        <li><span class="tf-nc">Pippo</span>           
          <ul>
            <li><span class="tf-nc">Pluto</span></li>
            <li><span class="tf-nc">Paperino</span>
              <ul>
                <li><span class="tf-nc">Paperina</span>
                  <ul>
                   <li><span class="tf-nc">Minnie</span></li>
                  </ul>
                <li><span class="tf-nc">Paperone</span>
                <li><span class="tf-nc">Paperoga</span>
                </li>
              </ul>
               </li>
            </li>
            <li><span class="tf-nc">Gambadilegno</span></li>
          </ul>
        </li>
        <li><span class="tf-nc">Topolino</span>
          <ul>
            <li><span class="tf-nc">Basettoni</span></li>
            <li><span class="tf-nc">Clarabella</span>
            <li><span class="tf-nc">Paperinik</span>           
             <ul>
              <li><span class="tf-nc">Orazio</span></li>
             </ul>
            </li>
          </ul>       
        </li>
      </ul>
    </li>
  </ul>
</div>

Ora, farlo a mano è piuttosto semplice per me, ma essendo a zero di Lazarus, vorrei che fosse lui, facendo il parsing del file di esempio (quello estratto dal DB), a crearmi la struttura del <ul> <li>, per automatizzare la creazione di viste (talvolta con centinaia di elementi).

Grazie a chi vorrà aiutarmi

 

Titolo: Re:Creazione di output html con lazarus
Inserito da: xinyiman - Ottobre 25, 2019, 12:03:30 pm
Concettualmente dai tuoi dati sembrerebbe che mancano delle informazioni per fare quello che vuoi tu. Ad esempio ad ogni voce dovrebbe essere corrisposta un id che identifica la voce, e anche un id padre che identifica qual'è l'id del nodo superiore. Altrimenti è impossibile fare quello che chiedi
Titolo: Re:Creazione di output html con lazarus
Inserito da: nomorelogic - Ottobre 25, 2019, 12:42:37 pm
partirei dal DOM, anzi da THTMLDocument (che eredita da TDOMLDocument), se non ricordo male è nella unit dom_html del package fcl-xml.

Chiaramente il parser della tua struttura dati lo dovrai fare tu, ma credo che questo possa essere un buon approccio.
Titolo: Re:Creazione di output html con lazarus
Inserito da: 00261 - Ottobre 25, 2019, 12:46:52 pm
Concettualmente dai tuoi dati sembrerebbe che mancano delle informazioni per fare quello che vuoi tu. Ad esempio ad ogni voce dovrebbe essere corrisposta un id che identifica la voce, e anche un id padre che identifica qual'è l'id del nodo superiore. Altrimenti è impossibile fare quello che chiedi
Vedo con piacere che la mente del programmatore è diversa da quella del sistemista  ;D
Si, potresti avere ragione, ma dal file del db ho estratto solo il minimo indispensabile, e credimi, quello che chiedi è presente in quel file di esempio:

Disney è il nodo di livello 0 ed è il padre di tutti i nodi di livello 1 (zero virgole = livello zero, una virgola = livello 1)
quindi Pippo e Topolino sono i figli di Disney,

Pippo è il padre di Paperino che lo è di paperina che lo è di minnie.

Vedi, la semplicità della rappresentazione di noi vecchi  ;)
Titolo: Re:Creazione di output html con lazarus
Inserito da: 00261 - Ottobre 25, 2019, 12:50:38 pm
partirei dal DOM, anzi da THTMLDocument (che eredita da TDOMLDocument), se non ricordo male è nella unit dom_html del package fcl-xml.

Chiaramente il parser della tua struttura dati lo dovrai fare tu, ma credo che questo possa essere un buon approccio.

Non ho la minima idea di cosa tu mi abbia detto di fare!  ;D ;D ;D

Io pensavo di scrivere in un file ti testo le stringhe html per ricreare la pagina e poi eseguirla con il browser di default. Non voglio certo visualizzarla con Lazarus
L'applicazione dovrebbe solo automatizzare il parsing del file, ma è proprio quello che non so fare...  :o
Titolo: Re:Creazione di output html con lazarus
Inserito da: Stilgar - Ottobre 25, 2019, 01:13:15 pm
Ciao

Per iniziare, così in modo semplice potresti:
Usare una TStringList per leggere il file.
Tramite "Lines" puoi ottenere ogni singola riga.
Conti le "," prima del test che ti interessa (la banda disney nel tuo esempio).
Inizierei da lì insomma.

Stilgar


Titolo: Re:Creazione di output html con lazarus
Inserito da: nomorelogic - Ottobre 25, 2019, 01:15:53 pm
ok, diciamo che devi fare 2 procedure
1) lettura file
2) generazione html

la mi risposta era relativa al problema (2)
vedo però che hai in mente di generare le stringhe html in un file, penso vada bene ugualmente ma dopo ti proporrei di rifarlo col THTMLDocument così che puoi vedere la differenza ;)

problema (1): L'applicazione dovrebbe solo automatizzare il parsing del file
se vogliamo rimanere ad un livello fai-da-te potrei dirti di usare una TStringList: carichi tutto il file e poi ti passi riga riga e ti generi l'HTML
esempio:
Codice: [Seleziona]
procedure ....
var sl: TStringList;
begin
  sl:=TStringList.Create;
  try
    sl.LoadFromFile(...);

   // loop per scansione righe e generazione HTML

  finally
    sl.Free;
  end;
end;



Edit:
stilgar mi hai fregato di un soffio ;)
Titolo: Re:Creazione di output html con lazarus
Inserito da: Stilgar - Ottobre 25, 2019, 01:20:58 pm
Il famoso filo di lana :)
Titolo: Re:Creazione di output html con lazarus
Inserito da: 00261 - Ottobre 25, 2019, 01:26:27 pm
ahahah! Vedo che c'è competizione! :-)
Grazie!
Intanto mi leggo un pò di esempi sul'uso delle tstringlist e poi su come implementare i loop.

Buona fortuna a me! 
Titolo: Re:Creazione di output html con lazarus
Inserito da: 00261 - Ottobre 25, 2019, 10:57:48 pm
Eccomi ancora…
È successo quanto segue:

    • Sono riuscito ad “infilare” il file nella tstringlist (piuttosto facile)
    • Poi con il for do ho fatto il loop che mi percorre tutte le stringhe.
    • Ho fatto una funzione che mi conta le virgole e mi restituisce il “livello”
    • Ho imparato come scrivere in un file.
    • Quello che non riesco a fare è capire come montare la struttura corretta, usando i dati che sto “parsando”, per ottenere il giusto output.

 :'( :'( :'(

Va bene dai, fino a martedi scorso non sapevo neppure che faccia avesse Lazarus, se continuo così tra qualche giorno smetterò di dargli del Voi e passerò al Lei! :-)

In ogni caso un aiutino non sarebbe male!
Titolo: Re:Creazione di output html con lazarus
Inserito da: Stilgar - Ottobre 26, 2019, 08:28:22 am
Se per iniziare le idee sono più o meno le stesse, per l'organizzazione del resto è un pochino il far West.

Di base un documento html è un insieme di nodi.  Ogni nodo può avere uno o più sotto nodi.
Ora dipende da quanto vuoi sbatterti.

Esistono delle classi pronte in freepascal per manipolare il dom. Il supporto non è completo, quindi se hai esperienza con altri linguaggi potresti trovare delle carenze. Le cose importanti ci sono però.
Concettualmente potresti usare quelle per creare in memoria il documento html e poi usarle per salvarlo su disco.

Un altro modo, vecchio e più impegnativo, è tradurre direttamente in html il testo che stai intercettando in lettura.

Per iniziare ti consiglierei di usare le classi pronte.

Stilgar
Titolo: Re:Creazione di output html con lazarus
Inserito da: nomorelogic - Ottobre 26, 2019, 08:46:54 am
se ci mostri il codice che hai buttato giù possiamo darti una mano
anche la funzione che conta le virgole e restituisce il livello è importante

il DOM è il modo migliore ma penso che l'HTML si potrebbe fare anche scrivendo "a mano" (alla fine si tratta di generare un brano di HTML e non una pagina completa)
Titolo: Re:Creazione di output html con lazarus
Inserito da: 00261 - Ottobre 27, 2019, 01:38:03 am
La funzione per contare le virgole è la seguente:

Codice: [Seleziona]
Function ContaVirgole(T:String):Integer;
Var
  MyParse: TStringList;
  Conta,I:integer;
begin
   MyParse:=TStringList.Create;
   MyParse.StrictDelimiter:=True;
   MyParse.Delimiter := ',';
   MyParse.DelimitedText:=T;

   Conta:=0;
   For I:=0 to MyParse.Count -1 do
     begin
        If Trim(MyParse[I])='' then
         Begin
           Inc(Conta);
         end
        else
         Begin
           Result:=Conta;
           Break;
         end;
     end;

end; 
   

Per fare lo split ed eliminare la parte di stringa che non mi serve e le virgole è questa:

Codice: [Seleziona]
Function Splittamelo(T:String):string;
var
MyParse: TStringList;
begin
MyParse:=TStringList.Create;
MyParse.StrictDelimiter:=True;
MyParse.Delimiter := ':';
MyParse.DelimitedText:=T;
Result:= StringReplace(MyParse[0],',','', [RfReplaceall]);
MyParse.Free;
end; 

Sto lavorando al parsing del file ma sto facendo delle cialtronate senza precedenti... Impresentabili! :-(

Appena avrò qualcosa di cui possa non "vergognarmi" la posto! :-)

                 
Titolo: Re:Creazione di output html con lazarus
Inserito da: nomorelogic - Ottobre 27, 2019, 10:27:05 am
vedo che ti ci metti d'impegno ;) bene

noto che in Splittamelo hai fatto bene invocando MyParse.Free mentre in ContaVirgole te ne sei dimenticato

probabilmente ContaVirgole potrebbe restituire tutti e 2 i valori
Titolo: Re:Creazione di output html con lazarus
Inserito da: nomorelogic - Ottobre 27, 2019, 11:19:40 am
mi sono permesso di fare qualche esperimento

in particolare:


Codice: [Seleziona]
program project_00261;

uses sysutils, Classes;

Function ContaVirgole(T:String):Integer;
Var
  MyParse: TStringList;
  Conta,I:integer;
begin
   MyParse:=TStringList.Create;
   MyParse.StrictDelimiter:=True;
   MyParse.Delimiter := ',';
   MyParse.DelimitedText:=T;

   Conta:=0;
   For I:=0 to MyParse.Count -1 do
     begin
        If Trim(MyParse[I])='' then
         Begin
           Inc(Conta);
         end
        else
         Begin
           Result:=Conta;
           Break;
         end;
     end;
   MyParse.Free;
end;

Function Splittamelo(T:String):string;
var
MyParse: TStringList;
begin
MyParse:=TStringList.Create;
MyParse.StrictDelimiter:=True;
MyParse.Delimiter := ':';
MyParse.DelimitedText:=T;
Result:= StringReplace(MyParse[0],',','', [RfReplaceall]);
MyParse.Free;
end;


Procedure ContaSplitta(T:String; out Virgole: integer; out TestoSplittato: string);
Var
  MyParse: TStringList;
  Conta,I:integer;
begin
   MyParse:=TStringList.Create;
   MyParse.StrictDelimiter:=True;
   MyParse.Delimiter := ',';
   MyParse.DelimitedText:=T;

   Conta:=0;
   For I:=0 to MyParse.Count -1 do
     begin
        If Trim(MyParse[I])='' then
         Begin
           Inc(Conta);
         end
        else
         Begin
           Virgole:=Conta;
           Break;
         end;
     end;

   // calcola testo splittato
   TestoSplittato:=copy(T, Conta + 1, Length(T) - Conta);

   MyParse.Free;
end;




  procedure Test_ContaSplitta(sl: TStringList);
  var I: integer;
      s: string;
      ResVirgole: integer;
      ResSplit: string;
   begin
     Writeln('Test_ContaSplitta');
     Writeln;
      for I := 0 to sl.Count - 1 do
       begin
          ContaSplitta(sl[I], ResVirgole, ResSplit);
          s := Format('Testo: %-20.20s - Livello: %2d - Split: %s',
                      [
                       sl[I],
                        ResVirgole,
                        ResSplit
                      ] );
          Writeln( s );
       end;
  end;

  procedure Test_ContaVirgole_e_Splittatamelo(sl: TStringList);
  var I: integer;
      s: string;

  begin
     Writeln('Test_ContaVirgole_e_Splittatamelo');
     Writeln;

     for I := 0 to sl.Count - 1 do
       begin
          s := Format('Testo: %-20.20s - Livello: %2d - Split: %s',
                      [
                        sl[I],
                        ContaVirgole(sl[I]),
                        Splittamelo(sl[I])
                      ] );
          Writeln( s );
       end;
  end;


  procedure Test_Scansione(sl: TStringList);
  const INIZIO_LIVELLO = 'inizio livello';
        FINE_LIVELLO = 'fine livello';
  var I, Livello, ResLivello: integer;
      s, ResSplittato: string;
  begin
     Livello:= -1;
     for I:=0 to sl.Count-1 do
       begin
          s:=sl[I];
          ContaSplitta(s, ResLivello, ResSplittato);

          // test nuovo livello
          if ResLivello > Livello then
           begin
             Livello:=ResLivello;
             WriteLn(StringOfChar(' ', Livello*2) + INIZIO_LIVELLO);
           end;

          // test fine livello
          if ResLivello < Livello then
           begin
             WriteLn(StringOfChar(' ', Livello*2) + FINE_LIVELLO);
             Livello:=ResLivello;
           end;

          // scrittura elemento
          WriteLn( StringOfChar(' ', Livello*2) + ResSplittato);


       end;

  end;


var Albero: TStringList;

begin
  Albero:=TStringList.Create;
  try
    // valorizza Albero a runtime
    Albero.Add('Disney');
    Albero.Add(',Pippo');
    Albero.Add(',,Pluto');
    Albero.Add(',,Paperino');
    Albero.Add(',,,Paperina');
    Albero.Add(',,,,Minnie');
    Albero.Add(',,,Paperone');
    Albero.Add(',,,Paperoga');
    Albero.Add(',,Gambadilegno');
    Albero.Add(',Topolino');
    Albero.Add(',,Basettoni');
    Albero.Add(',,Clarabella');
    Albero.Add(',,Paperinik');
    Albero.Add(',,,Orazio');


    Test_ContaVirgole_e_Splittatamelo(Albero);
    WriteLn;
    WriteLn;
    WriteLn;
    Test_ContaSplitta(Albero);

    WriteLn;
    WriteLn;
    WriteLn;
    Test_Scansione(Albero);

  finally
    Albero.Free;
  end;


end.
Titolo: Re:Creazione di output html con lazarus
Inserito da: antoniog - Ottobre 27, 2019, 05:04:42 pm
prova così:
crea una form mettici un campo memo e un pulsante.
il codice deve essere aggiustato con i <ul> </ul> e <li> </li> come ti servono ma come esempio penso che ti possa servire.
Codice: [Seleziona]

procedure TForm1.Button1Click(Sender: TObject);
var
F : textfile;
ab : string;
i, l : integer;
begin
  memo1.Clear;
  AssignFile(F, '/home/a.../Scrivania/db.txt');
  Reset(F);
  l:=1;
  while not EOF(F) do begin
    i:=0;
    ReadLn(F, ab);
    While (Pos(',', ab) > 0) Do
      begin
       Delete(ab, Pos(',', ab), 1);
       i:=i+1;
     end;
    if (i=4) and (l=1) then  memo1.Append('<ul  style="  background-color: #BFBFBF;">');
    if l>1 then
    case i of
     0 : memo1.Append('<li><a  href="....">'+ab+'</a></li>');
     1 : memo1.Append('<ul ><li><a  href="....">'+ab+ '</a></li>');
     2 : memo1.Append('</ul ></li><li><a  href="....">'+ab+ '</a></li>');
     3 : memo1.Append('<ul ></li><li><a  href="....">'+ab+ '</a></li>');
     4 : memo1.Append('<ul ></li><li><a  href="....">'+ab+ '</a></li>');
     //showmessage(inttostr(i));
    end;
   l:=l+1;
end;
   memo1.Append('</ul></ul ></ul >');
CloseFile(F);
  memo1.Lines.SaveToFile('/home/a.../Scrivania/db.html');
end;   
Titolo: Re:Creazione di output html con lazarus
Inserito da: 00261 - Ottobre 27, 2019, 11:53:06 pm
mi sono permesso di fare qualche esperimento

Grazie,
questa settimana tornerò a lavorare (per fortuna), così avrò poco tempo da dedicare all'attività ludico-ricreativa, ma, sebbene a colpo d'occhio non abbia capito un piffero del codice che hai buttato giù, sono convinto che il fatto di impegnarmi a comprenderlo mi sarà di grande aiuto per imparare.... Quindi, ti prometto che faro il bravo studente! Mi riservo il diritto di chiedere quello che non capisco e di cui non trovo informazioni su internet che siano alla mia portata.

Appena avrò nuovi sviluppi sarà mia premura postarli qui!

Al capo dei Fremen invece chiederei lumi su cosa sia il Dom, ma lascerò il quesito a duckduck go! :-)

P.S.
Il Pascal è proprio strano, ma mi piace assai...

Titolo: Re:Creazione di output html con lazarus
Inserito da: 00261 - Ottobre 27, 2019, 11:55:33 pm
prova così:
crea una form mettici un campo memo e un pulsante.
il codice deve essere aggiustato con i <ul> </ul> e <li> </li> come ti servono ma come esempio penso che ti possa servire.


Vale la stessa risposta che ho dato a nomorelogic...
Grazie anche a te...
Titolo: Re:Creazione di output html con lazarus
Inserito da: Stilgar - Ottobre 28, 2019, 07:26:40 am
Ciao.

Il Dom viene descritto  https://it.m.wikipedia.org/wiki/Document_Object_Model (https://it.m.wikipedia.org/wiki/Document_Object_Model)

In soldoni sono delle strutture logiche che vengono convertite in classi e interfaccie nei linguaggi di programmazione.

Puoi manipolare documenti che siano strutturati.

Stilgar
Titolo: Re:Creazione di output html con lazarus
Inserito da: nomorelogic - Ottobre 28, 2019, 09:30:00 am
Al capo dei Fremen invece chiederei...

per un attimo avevo letto Femen (senza la "r") e mi erano venute in mente altro tipo di Dune  ;D ;D ;D
Titolo: Re:Creazione di output html con lazarus
Inserito da: Stilgar - Ottobre 28, 2019, 09:56:13 am
....