2009-09-01 15 views
8

Ho bisogno di prendere due blocchi di testo con tag html e renderizzare un confronto: unire i due blocchi di testo e quindi evidenziare cosa è stato aggiunto o rimosso da una versione alla successiva.Come mostrare un confronto di 2 blocchi di testo html

ho usato la classe PEAR Text_Diff a rendere con successo il confronto di pianura testo, ma quando provo a lanciare il testo con tag html in esso, diventa brutto. A causa della parola e degli algoritmi di confronto basati sui caratteri usati dalla classe, i tag html si rompono e finisco con cose brutte come <p><span class="new"> </</span>p>. Si massacra l'html.

C'è un modo per generare un confronto di testo preservando il markup html originale valido?

Grazie per l'aiuto. Ci sto lavorando da settimane: [

Questa è la soluzione migliore che potessi pensare: trovare/sostituire ogni tipo di tag html con 1 carattere speciale non standard come il logo apple (opt shift k), rendere il confronto con questo tipo di markdown primitivo, quindi ripristinare i caratteri non standard in tag. Qualche feedback?

risposta

1

Il problema sembra essere che il vostro programma diff dovrebbe essere trattare tag HTML esistenti come i token atomiche piuttosto che come singoli personaggi.

Se il motore ha la capacità di limitarsi a lavorare sui limiti delle parole, vedere se è possibile ignorare la funzione che determina i limiti delle parole in modo da riconoscere e considerare i tag HTML come una singola "parola".

Si potrebbe anche fare come si dice e creare un dizionario di ricerca di tag HTML distinti che sostituisce ciascuno con un valore Unicode inutilizzato distinto (penso che ci siano alcuni intervalli definiti dall'utente che è possibile utilizzare). Tuttavia, se lo fai, qualsiasi modifica al markup sarà trattata come se fosse una modifica alla parola precedente o successiva, perché il carattere Unicode diventerà parte di quella parola al tokenizzatore. Aggiungere uno spazio prima e dopo ciascuno dei tuoi caratteri Unicode token manterrebbe le modifiche dei tag HTML separate dalle modifiche al testo normale.

+0

Il token find/replace unicode è ciò che ha funzionato alla fine. Ho appena fatto un key => array di valori con ogni tag di apertura e chiusura e il suo carattere unicode associato. Quindi ho generato il confronto e invertito il token/tag swap. –

+1

Ho anche trovato che lo script Simple Diff di Paul Butler funziona molto meglio per il testo lungo rispetto al pacchetto PEAR. PEAR focalizzato parola per parola mentre la configurazione di Butcher ha prodotto un risultato migliore con le differenze rimanenti raggruppate come stringhe. Link: http://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php –

+0

Ciao @SteveG., Che tipo di unicode hai usato? Perché se viene trattato con "\\ u123" o "% 3C" per "<" alcuni algoritmi di diff non considerano la stessa parola. E se mappo usando i tasti solo con numeri come lettere, come posso garantire che non entrerà in conflitto con qualcos'altro sulla parte di testo di html? Grazie! http://i.imgur.com/OAJUAP1.png – Luccas

0

provare a eseguire i blocchi HTML attraverso questa funzione prima:

htmlentities(); 

Questo dovrebbe convertire i propri "<" 's e '>'' s nei loro codici corrispondenti, forse fissare il vostro problema.

//Example: 
$html_1 = "<html><head></head><body>Something</body></html>" 
$html_2 = "<html><head></head><body><p id='abc'>Something Else</p></body></html>" 

//Below code taken from http://www.go4expert.com/forums/showthread.php?t=4189. 
//Not sure if/how it works exactly 

$diff = &new Text_Diff(htmlentities($html_1), htmlentities($html_2)); 
$renderer = &new Text_Diff_Renderer(); 
echo $renderer->render($diff); 
+0

Grazie per la risposta rapida ... ma questo potrebbe effettivamente peggiorare il problema:/perché in tal caso i tag sarebbero convertiti in stringhe di char-char ancora più lunghe, che la classe di confronto si spezzerà. Il risultato finale deve essere un codice HTML valido in modo che possa essere visualizzato su una pagina Web. Non voglio che l'utente finale veda alcun tag html: devono vedere l'html renderizzato su una pagina. Il testo con cui ho a che fare può essere pensato come un blog - solo tag h, p, a e img. Voglio solo aggiungere l'evidenziazione per mostrare cosa è cambiato. –

3

Semplice Diff, da Paul Butler, sembra come se è stato progettato per fare esattamente quello che ti serve: http://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php

Avviso nel suo codice php che c'è un wrapper HTML: HTMLDiff ($ vecchio, $ nuova)

(Il suo post del blog su di esso: http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/

+0

Questo algoritmo funziona molto meglio di quello di PEAR. Grazie per aver segnalato la risorsa. –

+0

Grande. Sei piu 'che benvenuto. – micahwittman

1

Che ne dici di usare un hidml tidier/formattatore su ogni blocco prima? Questo creerà una "struttura" standard che il tuo diff potrebbe trovare più facile da inghiottire

0

Una copia della mia risposta da here.


Che dire DaisyDiff (Java e PHP vesions disponibili).

Le seguenti caratteristiche sono veramente bello:

  • Funziona con HTML mal formato che possono essere trovati "in the wild".
  • La differenza è più specializzata in HTML rispetto a quella dell'albero XML. La modifica di parte di un nodo di testo non causerà la modifica dell'intero nodo.
  • Oltre alla differenza visiva predefinita, la sorgente HTML può essere diffusa in modo coerente.
  • Fornisce descrizioni facili da comprendere delle modifiche.
  • La GUI predefinita consente una facile navigazione delle modifiche tramite scorciatoie da tastiera e collegamenti.
1

Mi chiedo che nessuno abbia menzionato HTMLDiff sulla base di MediaWiki Visual Diff. Fai un tentativo, stavo cercando qualcosa come te e l'ho trovato abbastanza utile.

+0

Lo stiamo usando, ma a volte restituisce un paragrafo vuoto (quando non ci sono differenze, si suppone che restituisca l'originale invariato, ma in questo caso ci * sono * differenze) e altre volte sposta HTML attorno (un paragrafo rimosso viene unito al paragrafo prima di esso quando indica che è stato rimosso). Ha solo bisogno di un po 'di amore. –

+0

E poi c'è questo bug ([HTMLDiff è terribilmente rotto] (https://phabricator.wikimedia.org/T21859)) che è stato risolto rimuovendo HTMLDiff da MediaWiki. :( –

+0

@DavidHarkness parte del motivo è che gli sviluppatori di MediaWiki non conoscono nessuno o lo sta usando. Il feedback su phabricator.wikimedia.org sarebbe molto utile. – Nemo

Problemi correlati