/// <summary> /// Checks if any source document is open, and join the multiple source Word documents to /// a single file. /// </summary> /// <param name="msWord">Word instace that will do this work.</param> /// <returns>Path to a single Word file containing all source documents. If there is a /// single source file, it will return that file path.</returns> private string CheckAndJoinWordSourceFiles(MSWord msWord) { // Check any source file is open: foreach (string sourceFile in Project.SourceFiles) { if (msWord.IsOpen(sourceFile)) { throw new Exception("The file " + sourceFile + " is already open. You must to close it before generate the help."); } } if (Project.SourceFiles.Count == 1) { return((string)Project.SourceFiles[0]); } // Join multiple documents to a temporal file: string joinedDocument = Path.GetTempFileName(); // Add DOC extension: joinedDocument += ".doc"; UI.Log("Joining documents to a single temporal file : " + joinedDocument, ChmLogLevel.INFO); msWord.JoinDocuments(Project.SourceFiles.ToArray(), joinedDocument); return(joinedDocument); }
/// <summary> /// Open source files. /// If they are Word, they will be converted to HTML. /// </summary> private void OpenSourceFiles() { MSWord msWord = null; try { string archivoFinal = (string)Project.SourceFiles[0]; IsMSWord = MSWord.IsWordDocument(archivoFinal); MSWordHtmlDirectory = null; // Si es un documento word, convertirlo a HTML filtrado if (IsMSWord) { msWord = new MSWord(); archivoFinal = ConvertWordSourceFiles(msWord); // Be sure we have closed word, to avoid overlapping between the html read // and the reading from chmprocessor: msWord.Dispose(); msWord = null; } else { // There is a single source HTML file. MainSourceFile = (string)Project.SourceFiles[0]; } if (UI.CancellRequested()) { return; } // TODO: Check if this should be removed. if (AppSettings.UseTidyOverInput) { new TidyParser(UI).Parse(archivoFinal); } if (UI.CancellRequested()) { return; } // Load the HTML file: HtmlDoc = new HtmlDocument(); HtmlDoc.Load(archivoFinal); } finally { if (msWord != null) { msWord.Dispose(); msWord = null; } } }
/// <summary> /// Open a xml file with a ChmProject object serialized OR create a default /// ChmProject for a Word/HTML file. /// </summary> /// <param name="filePath">Path to the ChmProject file or to the Word/Html file</param> /// <returns>The ChmProject readed or the default project for the Word/Html file</returns> static public ChmProject OpenChmProjectOrWord(string filePath) { if (IsChmProjectFile(filePath)) { // It's a CHMProcessor file return(Open(filePath)); } else if (MSWord.IsHtmlDocument(filePath) || MSWord.IsWordDocument(filePath)) { // A word/html file return(CreateProjectforHtmlWordFile(filePath)); } else { throw new Exception("Unknown file extension " + Path.GetExtension(filePath)); } }
/// <summary> /// Throws an exception if the source file cannot be added to the source files list. /// </summary> /// <param name="sourceFilePath">Source file to check</param> private void CheckAddSourceFile(string sourceFilePath) { if (SourceFiles.Count == 0) { return; } bool currentListIsHtml = MSWord.IsHtmlDocument(SourceFiles[0]); bool fileIsHtml = MSWord.IsHtmlDocument(sourceFilePath); if ((currentListIsHtml && !fileIsHtml) || (!currentListIsHtml && fileIsHtml)) { throw new Exception("HTML and Word documents cannot be mixed as source documents"); } if (fileIsHtml) { throw new Exception("Only one HTML document can be used as source document"); } }
/// <summary> /// Open source files, if they are MS Word documents. /// It joins and store them to a HTML single file. /// </summary> /// <param name="msWord">Word instace that will do this work.</param> /// <returns>The HTML joined version of the MS Word documents</returns> private string ConvertWordSourceFiles(MSWord msWord) { MainSourceFile = CheckAndJoinWordSourceFiles(msWord); if (UI.CancellRequested()) { return(null); } UI.Log("Convert file " + MainSourceFile + " to HTML", ChmLogLevel.INFO); string nombreArchivo = Path.GetFileNameWithoutExtension(MainSourceFile); MSWordHtmlDirectory = Path.Combine(Path.GetTempPath(), nombreArchivo); if (Directory.Exists(MSWordHtmlDirectory)) { Directory.Delete(MSWordHtmlDirectory, true); } else if (File.Exists(MSWordHtmlDirectory)) { File.Delete(MSWordHtmlDirectory); } Directory.CreateDirectory(MSWordHtmlDirectory); // Rename the file to a save name. If there is spaces, as example, // links to embedded images into the document are not found. //string finalFile = dirHtml + Path.DirectorySeparatorChar + nombreArchivo + ".htm"; // hmm. Probably a MSHTML bug? Reverted. A bug about this was reported (http://sourceforge.net/p/chmprocessor/bugs/24/) //string finalFile = MSWordHtmlDirectory + Path.DirectorySeparatorChar + ChmDocumentNode.ToSafeFilename(nombreArchivo) + ".htm"; string finalFile = Path.Combine(MSWordHtmlDirectory, nombreArchivo + ".htm"); if (!msWord.SaveWordToHtml(MainSourceFile, finalFile)) { UI.Log("Warning: There was a time out waiting to close the word document", ChmLogLevel.WARNING); } return(finalFile); }
/// <summary> /// Open source files, if they are MS Word documents. /// It joins and store them to a HTML single file. /// </summary> /// <param name="msWord">Word instace that will do this work.</param> /// <returns>The HTML joined version of the MS Word documents</returns> private string ConvertWordSourceFiles(MSWord msWord) { MainSourceFile = CheckAndJoinWordSourceFiles(msWord); if (CancellRequested()) return null; log("Convert file " + MainSourceFile + " to HTML", 2); string nombreArchivo = Path.GetFileNameWithoutExtension(MainSourceFile); dirHtml = Path.GetTempPath() + Path.DirectorySeparatorChar + nombreArchivo; if (Directory.Exists(dirHtml)) Directory.Delete(dirHtml, true); else if (File.Exists(dirHtml)) File.Delete(dirHtml); Directory.CreateDirectory(dirHtml); // Rename the file to a save name. If there is spaces, for example, // links to embedded images into the document are not found. //string finalFile = dirHtml + Path.DirectorySeparatorChar + nombreArchivo + ".htm"; string finalFile = dirHtml + Path.DirectorySeparatorChar + NodoArbol.ToSafeFilename(nombreArchivo) + ".htm"; msWord.SaveWordToHtml(MainSourceFile, finalFile); return finalFile; }
/// <summary> /// Checks if any source document is open, and join the multiple source Word documents to /// a single file. /// </summary> /// <param name="msWord">Word instace that will do this work.</param> /// <returns>Path to a single Word file containing all source documents. If there is a /// single source file, it will return that file path.</returns> private string CheckAndJoinWordSourceFiles(MSWord msWord) { // Check any source file is open: foreach (string sourceFile in Project.SourceFiles) { if (msWord.IsOpen(sourceFile)) throw new Exception("The file " + sourceFile + " is already open. You must to close it before generate the help."); } if (Project.SourceFiles.Count == 1) return (string) Project.SourceFiles[0]; // Join multiple documents to a temporal file: string joinedDocument = Path.GetTempFileName(); // Add DOC extension: joinedDocument += ".doc"; log("Joining documents to a single temporal file : " + joinedDocument, 2); msWord.JoinDocuments(Project.SourceFiles, joinedDocument); return joinedDocument; }
/// <summary> /// Generate a XPS file for the document. /// </summary> private void BuildXps() { log("Generating XPS file", 2); try { MSWord word = new MSWord(); word.SaveWordToXps(MainSourceFile, Project.XpsPath); } catch (Exception ex) { log("Something wrong happened with the XPS generation. Remember you must to have Microsoft Office 2007 and the" + "pdf/xps generation add-in (http://www.microsoft.com/downloads/details.aspx?FamilyID=4D951911-3E7E-4AE6-B059-A2E79ED87041&displaylang=en)", 1); log(ex); } }
/// <summary> /// Generate a PDF file for the document. /// </summary> private void BuildPdf() { try { log("Generating PDF file", 2); if (Project.PdfGeneration == ChmProject.PdfGenerationWay.OfficeAddin) { MSWord word = new MSWord(); word.SaveWordToPdf(MainSourceFile, Project.PdfPath); } else { PdfPrinter pdfPrinter = new PdfPrinter(); pdfPrinter.ConvertToPdf(MainSourceFile, Project.PdfPath); } } catch (Exception ex) { if (Project.PdfGeneration == ChmProject.PdfGenerationWay.OfficeAddin) log("Something wrong happened with the PDF generation. Remember you must to have Microsoft Office 2007 and the" + "pdf/xps generation add-in (http://www.microsoft.com/downloads/details.aspx?FamilyID=4D951911-3E7E-4AE6-B059-A2E79ED87041&displaylang=en)", 1); else log("Something wrong happened with the PDF generation. Remember you must to have PdfCreator (VERSION " + PdfPrinter.SUPPORTEDVERSION + " AND ONLY THIS VERSION) installed into your computer to " + "generate a PDF file. You can download it from http://www.pdfforge.org/products/pdfcreator/download", 1); log(ex); } }
/// <summary> /// Open source files. /// If they are not word, they will be converted to HTML. /// </summary> private void OpenSourceFiles() { MSWord msWord = null; try { string archivoFinal = (string)Project.SourceFiles[0]; esWord = MSWord.ItIsWordDocument(archivoFinal); dirHtml = null; // Si es un documento word, convertirlo a HTML filtrado if (esWord) { msWord = new MSWord(); archivoFinal = ConvertWordSourceFiles(msWord); // Be sure we have closed word, to avoid overlapping between the html read // and the reading from chmprocessor: msWord.Dispose(); msWord = null; } else // There is a single source HTML file. MainSourceFile = (string)Project.SourceFiles[0]; if (CancellRequested()) return; if (AppSettings.UseTidyOverInput) new TidyParser(UI).Parse(archivoFinal); if (CancellRequested()) return; // Prepare loading: HTMLDocumentClass docClass = new HTMLDocumentClass(); IPersistStreamInit ips = (IPersistStreamInit)docClass; ips.InitNew(); // Create a timer, to be sure that HTML file load will not be hang up (Sometime happens) timerTimeout = new System.Windows.Forms.Timer(); timerTimeout.Tick += new System.EventHandler(this.timer_Tick); timerTimeout.Interval = 60 * 1000; // 1 minute timerTimeout.Enabled = true; // Load the file: IHTMLDocument2 docLoader = (mshtml.IHTMLDocument2)docClass.createDocumentFromUrl( archivoFinal , null); System.Windows.Forms.Application.DoEvents(); System.Threading.Thread.Sleep(1000); String currentStatus = docLoader.readyState; log("Reading file " + archivoFinal + ". Status: " + currentStatus , 2 ); while (currentStatus != "complete" && timerTimeout.Enabled) { System.Windows.Forms.Application.DoEvents(); System.Threading.Thread.Sleep(500); String newStatus = docLoader.readyState; if (newStatus != currentStatus) { log("Status: " + newStatus, 2); if (currentStatus == "interactive" && newStatus == "uninitialized") { // f*****g shit bug. Try to reload the file: log("Warning. Something wrong happens loading the file. Trying to reopen " + archivoFinal , 2); docClass = new HTMLDocumentClass(); ips = (IPersistStreamInit)docClass; ips.InitNew(); docLoader = (mshtml.IHTMLDocument2)docClass.createDocumentFromUrl(archivoFinal, null); newStatus = docLoader.readyState; log("Status: " + newStatus, 2); } currentStatus = newStatus; } } if (!timerTimeout.Enabled) log("Warning: time to load file expired.", 1); timerTimeout.Enabled = false; // Get a copy of the document: HTMLDocumentClass newDocClass = new HTMLDocumentClass(); iDoc = (IHTMLDocument2)newDocClass; object[] txtHtml = { ((IHTMLDocument3)docLoader).documentElement.outerHTML }; iDoc.writeln(txtHtml); try { // Needed, otherwise some characters will not be displayed well. iDoc.charset = docLoader.charset; } catch (Exception ex) { log("Warning: Cannot set the charset \"" + docLoader.charset + "\" to the html document. Reason:" + ex.Message, 1); log(ex); } } finally { if (msWord != null) { msWord.Dispose(); msWord = null; } } }