/// <summary> /// Builds the sections tree of the document. /// </summary> /// <param name="cutLevel">HTML Header level that will contain an entire HTML page</param> /// <param name="root">Root of the HTML document</param> /// <param name="ui">The application log. it can be null.</param> public void AnalizarDocumento( int cutLevel , IHTMLElement root , UserInterface ui) { // Reservar el primer nodo para el contenido que venga sin titulo1, (portada,etc). NodoArbol sinSeccion = new NodoArbol( this.Raiz , null , ui); this.Raiz.Hijos.Add( sinSeccion ); // Analizar que nodos de headers se encuentran en el documento AnalizarDocumentoRecursivo( root , ui ); // Por defecto, todos los nodos al documento por defecto. El resto // ya ira cogiendo el valor de su archivo: this.Raiz.StoredAt( "1.htm" ); // Guardar en cada nodo en que archivo se habra guardado el nodo: int Cnt = 2; foreach( NodoArbol hijo in this.Raiz.Hijos ) AsignarNombreArchivos(hijo, ref Cnt, cutLevel); }
/// <summary> /// Tree section node constructor /// </summary> /// <param name="parent">Parent section of the section to create. null if the node to create is the root section.</param> /// <param name="node">HTML header tag for this section</param> /// <param name="ui">Application log. It can be null</param> public NodoArbol(NodoArbol parent, IHTMLElement node, UserInterface ui) { this.Padre = parent; this.Nodo = node; Hijos = new ArrayList(); Nivel = NivelNodo( node ); Archivo = ""; // Guardar la lista de los todos las referencias de este nodo ( nodos <A> con la propiedad "name") listaANames = new ArrayList(); if( node != null ) { IHTMLElementCollection col = (IHTMLElementCollection) node.children; foreach( IHTMLElement hijo in col ) { if (hijo is IHTMLAnchorElement) { // Remove empty spaces, because they will fail into the CHM. // The anchors to this will be replace too after. //listaANames.Add( ((IHTMLAnchorElement)hijo).name.Replace( " " , "" ) ); string processedName = ToSafeFilename( ((IHTMLAnchorElement)hijo).name ); if (processedName == null || processedName.Trim() == "") // It seems on HTML 5 and XHTML <a id="foo"> is used... processedName = ToSafeFilename( hijo.id ); if( processedName != null && processedName.Trim() != "" ) listaANames.Add(processedName); } } if( listaANames.Count == 0 ) { // Si no tiene ningun nombre, darle uno artificial: int numero = UltimoNumeroAname++; // Mm... // This is failing on UTF-16 / persian charset. Try to change the encoding to // the document encoding... string nombreNodo = "NODO" + numero.ToString().Trim(); //string nombreNodo = "a" + numero.ToString().Trim(); AddARefTagToNode(node, ui, nombreNodo); listaANames.Add(nombreNodo); } } }
/// <summary> /// Tree section node constructor /// </summary> /// <param name="parent">Parent section of the section to create. null if the node to create is the root section.</param> /// <param name="node">HTML header tag for this section</param> /// <param name="ui">Application log. It can be null</param> public NodoArbol(NodoArbol parent, IHTMLElement node, UserInterface ui) { this.Padre = parent; this.Nodo = node; Hijos = new ArrayList(); Nivel = NivelNodo( node ); Archivo = ""; // Guardar la lista de los todos las referencias de este nodo ( nodos <A> con la propiedad "name") listaANames = new ArrayList(); if( node != null ) { IHTMLElementCollection col = (IHTMLElementCollection) node.children; foreach( IHTMLElement hijo in col ) { if (hijo is IHTMLAnchorElement) { // Remove empty spaces, because they will fail into the CHM. // The anchors to this will be replace too after. //listaANames.Add( ((IHTMLAnchorElement)hijo).name.Replace( " " , "" ) ); string processedName = ToSafeFilename( ((IHTMLAnchorElement)hijo).name ); if (processedName == null || processedName.Trim() == "") // It seems on HTML 5 and XHTML <a id="foo"> is used... processedName = ToSafeFilename( hijo.id ); if( processedName != null && processedName.Trim() != "" ) listaANames.Add(processedName); } } if( listaANames.Count == 0 ) { // Si no tiene ningun nombre, darle uno artificial: int numero = UltimoNumeroAname++; string nombreNodo = "NODO" + numero.ToString().Trim(); string tagA = "<a name=\"" + nombreNodo + "\">"; try { node.insertAdjacentHTML("afterBegin", tagA); listaANames.Add(nombreNodo); } catch (Exception ex) { if( ui != null ) ui.log( new Exception("There was an error trying to add the tag " + tagA + " to the node " + node.outerHTML + " (wrong HTML syntax?). If " + "the source document is HTML, try to add manually an <a> tag manually. " + "The application needs a node of this kind on each section title " + "to make links to point it", ex ) ); } } } }
private void ListaArchivosGenerados( ArrayList lista , NodoArbol nodo ) { if( !nodo.Archivo.Equals("") && !lista.Contains(nodo.Archivo) ) lista.Add( nodo.Archivo); foreach( NodoArbol hijo in nodo.Hijos ) ListaArchivosGenerados( lista , hijo ); }
public ArbolCapitulos() { Raiz = new NodoArbol( null , null , null ); Raiz.Nivel = 0; }
private void UnificarNodos( NodoArbol nodo ) { try { if (nodo.Nodo != null && nodo.Nodo.innerText != null && nodo.body != null) { // Nodo con cuerpo: if (nodo.Nodo.innerText.Trim().Equals(nodo.body.innerText.Trim()) && nodo.Hijos.Count > 0) { // Nodo vacio y con hijos NodoArbol hijo = (NodoArbol)nodo.Hijos[0]; if (hijo.body != null) { // El hijo tiene cuerpo: Unificarlos. nodo.body.insertAdjacentHTML("beforeEnd", hijo.body.innerHTML); hijo.body = null; //hijo.GuardadoEn(nodo.Archivo); hijo.ReplaceFile(nodo.Archivo); } } } foreach (NodoArbol hijo in nodo.Hijos) UnificarNodos(hijo); } catch (Exception ex) { log( new Exception( "There was some problem when we tried to join the empty section " + nodo.Name + " with their children", ex ) ); } }
private string GenerarArbolHtml( NodoArbol nodo , int NivelMaximoTOC , int nivel ) { if( NivelMaximoTOC != 0 && nivel > NivelMaximoTOC ) return ""; string texto = ""; if( ! nodo.Href.Equals("") ) { // Verificar el nodo inicial, que puede no tener titulo: string nombre = ""; if( nodo.Nodo != null ) nombre = nodo.Nodo.innerText; else nombre = DEFAULTTILE; texto = "<li><a href=\"" + nodo.Href ; texto += "\">" + DocumentProcessor.HtmlEncode( nombre ) + "</a>"; } if( nodo.Hijos.Count > 0 ) { if( NivelMaximoTOC == 0 || nivel < NivelMaximoTOC ) { texto += "\n<ul>\n"; foreach( NodoArbol hijo in nodo.Hijos ) texto += GenerarArbolHtml( hijo , NivelMaximoTOC , nivel + 1 ) + "\n"; texto += "</ul>"; } } if( !texto.Equals("") ) texto += "</li>"; return texto; }
/// <summary> /// Adds a section to the section tree. /// The section will be added as child of the last section inserted with a level /// higher than then section /// </summary> /// <param name="nodo">HTML header tag with the title of the section</param> /// <param name="ui">Application log. It can be null</param> public void InsertarNodo( IHTMLElement node , UserInterface ui ) { // Ignorar cabeceras vacias (saltos de linea,etc. ) : if( !DocumentProcessor.EsHeader( node ) ) return; int nivel = NodoArbol.NivelNodo( node ); if( ultimoInsertado == null || nivel == 1 ) { ultimoInsertado = new NodoArbol( null, node , ui ); Raiz.NuevoHijo( ultimoInsertado ); } else { NodoArbol nuevoNodo = new NodoArbol( ultimoInsertado, node , ui ); if( ultimoInsertado.Nivel < nivel ) ultimoInsertado.Hijos.Add( nuevoNodo ); else { NodoArbol actual = ultimoInsertado.Padre; while( actual != Raiz && actual.Nivel >= nivel ) actual = actual.Padre; actual.NuevoHijo( nuevoNodo ); } ultimoInsertado = nuevoNodo; } }
protected void GenerarArbolDeContenidos( StreamWriter writer , NodoArbol nodo , int NivelMaximoTOC , int nivel ) { if( NivelMaximoTOC != 0 && nivel > NivelMaximoTOC ) return; writer.WriteLine( nodo.EntradaArbolContenidos ); if( nodo.Hijos.Count > 0 ) { writer.WriteLine( "<UL>" ); foreach( NodoArbol hijo in nodo.Hijos ) GenerarArbolDeContenidos( writer , hijo , NivelMaximoTOC , nivel + 1 ); writer.WriteLine( "</UL>" ); } }
public void GenerarIndice( Index index , NodoArbol nodo , int NivelMaximoIndice , int nivel ) { if( NivelMaximoIndice != 0 && nivel > NivelMaximoIndice ) return; index.AddNode( nodo ); //writer.WriteLine( nodo.EntradaArbolContenidos ); foreach( NodoArbol hijo in nodo.Hijos ) GenerarIndice( index , /*writer ,*/ hijo , NivelMaximoIndice , nivel + 1 ); }
/// <summary> /// Generate a java help table of contents xml file. /// </summary> /// <param name="writer">File where to store the TOC</param> /// <param name="currentNode">Node to process now</param> /// <param name="currentLevel">Current deep level of the node into the document tree</param> /// <param name="maxLevelTOC">Maximum deep level into the tree to generate the TOC.</param> public void GenerateJavaHelpTOC(StreamWriter writer, NodoArbol currentNode, int maxLevelTOC, int currentLevel) { if (maxLevelTOC != 0 && currentLevel > maxLevelTOC) return; if( currentNode.Nodo != null ) writer.WriteLine(currentNode.JavaHelpTOCEntry); foreach (NodoArbol child in currentNode.Hijos) GenerateJavaHelpTOC(writer, child, maxLevelTOC, currentLevel + 1); if (currentNode.Nodo != null && currentNode.Hijos.Count > 0) writer.WriteLine("</tocitem>"); }
public void AddNode( NodoArbol node ) { entriesList.Add( node ); }
private void UnificarNodos( NodoArbol nodo ) { if( nodo.Nodo != null && nodo.Nodo.innerText != null && nodo.body != null ) { // Nodo con cuerpo: if( nodo.Nodo.innerText.Trim().Equals( nodo.body.innerText.Trim() ) && nodo.Hijos.Count > 0 ) { // Nodo vacio y con hijos NodoArbol hijo = (NodoArbol) nodo.Hijos[0]; if( hijo.body != null ) { // El hijo tiene cuerpo: Unificarlos. nodo.body.insertAdjacentHTML("beforeEnd" , hijo.body.innerHTML); hijo.body = null; //hijo.GuardadoEn(nodo.Archivo); hijo.ReplaceFile(nodo.Archivo); } } } foreach( NodoArbol hijo in nodo.Hijos ) UnificarNodos( hijo ); }
private void GuardarDocumentos( string directory , string header , string footer , NodoArbol nodo , ArrayList archivosGenerados , WebIndex indexer ) { if( nodo.body != null ) { string texto = ""; if( nodo.body.innerText != null ) texto = nodo.body.innerText.Trim(); if( !texto.Equals("") ) { bool guardar = true; string titulo = ""; IHTMLElement seccion = null; seccion = SearchFirstCutNode( nodo.body ); if( seccion != null && seccion.innerText != null ) { titulo = seccion.innerText.Trim() ; if( titulo.Length == 0 ) guardar = false; } if( guardar ) { // hacer un preproceso de TODOS los nodos del cuerpo: IHTMLElementCollection col = (IHTMLElementCollection)nodo.body.children; foreach( IHTMLElement nodoBody in col ) PreProcesarNodo( nodoBody , null); // Generar el documento a guardar: IHTMLDOMNode domNode = (IHTMLDOMNode)nodo.body; IHTMLElement clonedBody = (IHTMLElement)domNode.cloneNode(true); // Si hay pie o cabecera, aƱadirlos al body: if (header != null && !header.Equals("")) clonedBody.insertAdjacentHTML("afterBegin", header); if (footer != null && !footer.Equals("")) clonedBody.insertAdjacentHTML("beforeEnd", footer); iDoc.title = titulo; AntesYDespuesBody(); string archivo = directory + Path.DirectorySeparatorChar + nodo.Archivo; Encoding encoding = Encoding.GetEncoding( iDoc.charset ); StreamWriter writer = new StreamWriter( archivo , false , encoding ); writer.WriteLine( textoAntesBody ); texto = clonedBody.outerHTML; // Parece que hay un bug por el cual pone about:blank en los links. Quitarlos: texto = texto.Replace( "about:blank" , "" ).Replace("about:" , "" ); writer.WriteLine( texto ); writer.WriteLine( textoDespuesBody ); writer.Close(); // Clean the files using Tidy TidyOutputFile(archivo); if (FirstChapterContent == null) { // This is the first chapter of the document. Store it clean, because // we will need after. FirstChapterContent = nodo.body.innerHTML.Replace("about:blank", "").Replace("about:", ""); } archivosGenerados.Add( archivo ); if (indexer != null) // Store the document at the full text search index: indexer.AddPage(nodo.Archivo, nodo.Title , clonedBody ); } } } foreach( NodoArbol hijo in nodo.Hijos ) GuardarDocumentos( directory , header , footer , hijo , archivosGenerados , indexer ); }
public void NuevoHijo( NodoArbol nodo ) { nodo.Padre = this; Hijos.Add( nodo ); }
private void AsignarNombreArchivos( NodoArbol nodo , ref int Cnt , int nivelCorte ) { if( nodo.Nodo != null && DocumentProcessor.IsCutHeader( nivelCorte , nodo.Nodo ) ) nodo.StoredAt( nodo.NombreArchivo( Cnt++ ) ); foreach( NodoArbol hijo in nodo.Hijos ) AsignarNombreArchivos( hijo , ref Cnt , nivelCorte ); }
/// <summary> /// Constructor del nodo /// </summary> /// <param name="padre">Nodo padre en el arbol de capitulos. Nulo si es la raiz</param> /// <param name="nodo">Nodo HTML header correspondiente. Nulo si es la raiz</param> public NodoArbol(NodoArbol padre, IHTMLElement nodo) { this.Padre = padre; this.Nodo = nodo; Hijos = new ArrayList(); Nivel = NivelNodo( nodo ); Archivo = ""; // Guardar la lista de los todos las referencias de este nodo ( nodos <A> con la propiedad "name") listaANames = new ArrayList(); if( nodo != null ) { IHTMLElementCollection col = (IHTMLElementCollection) nodo.children; foreach( IHTMLElement hijo in col ) { if (hijo is IHTMLAnchorElement) { // Remove empty spaces, because they will fail into the CHM. // The anchors to this will be replace too after. //listaANames.Add( ((IHTMLAnchorElement)hijo).name.Replace( " " , "" ) ); string processedName = ToSafeFilename( ((IHTMLAnchorElement)hijo).name ); listaANames.Add(processedName); } } if( listaANames.Count == 0 ) { // Si no tiene ningun nombre, darle uno artificial: int numero = UltimoNumeroAname++; string nombreNodo = "NODO" + numero.ToString().Trim(); string tagA = "<a name=\"" + nombreNodo + "\">"; nodo.insertAdjacentHTML( "afterBegin" , tagA ); listaANames.Add( nombreNodo ); } } }
private void GuardarDocumentos(string directory, HtmlPageDecorator decorator, NodoArbol nodo, ArrayList archivosGenerados, WebIndex indexer) { if( nodo.body != null ) { string texto = ""; if( nodo.body.innerText != null ) texto = nodo.body.innerText.Trim(); if( !texto.Equals("") ) { bool guardar = true; string titulo = ""; IHTMLElement seccion = null; seccion = SearchFirstCutNode( nodo.body ); if( seccion != null && seccion.innerText != null ) { titulo = seccion.innerText.Trim() ; if( titulo.Length == 0 ) guardar = false; } if( guardar ) { // hacer un preproceso de TODOS los nodos del cuerpo: IHTMLElementCollection col = (IHTMLElementCollection)nodo.body.children; foreach( IHTMLElement nodoBody in col ) PreprocessHtmlNode( nodoBody , null); // Save the section, adding header, footers, etc: string filePath = directory + Path.DirectorySeparatorChar + nodo.Archivo; decorator.ProcessAndSavePage(nodo.body, filePath, nodo.Name); if (FirstChapterContent == null) { // This is the first chapter of the document. Store it clean, because // we will need after. FirstChapterContent = nodo.body.innerHTML.Replace("about:blank", "").Replace("about:", ""); } archivosGenerados.Add(filePath); if (indexer != null) // Store the document at the full text search index: //indexer.AddPage(nodo.Archivo, nodo.Title, nodo.body); indexer.AddPage(nodo.Archivo, nodo.Name, nodo.body); } } } foreach( NodoArbol hijo in nodo.Hijos ) GuardarDocumentos( directory , decorator , hijo , archivosGenerados , indexer ); }