/// ------------------------------------------------------------------------------------ /// <summary> /// Updates the lds file which describes the writing system in Paratext. /// </summary> /// <param name="ldsFileName">Name of the LDS file.</param> /// <param name="normalStyle">The normal style.</param> /// <param name="ws">The HVO of the writing system for the current export.</param> /// <param name="fileWriterLDS">file writer for updating the Paratext LDS file</param> /// ------------------------------------------------------------------------------------ public bool UpdateLdsFile(string ldsFileName, UsfmStyEntry normalStyle, int ws, FileWriter fileWriterLDS) { try { string ldsContents; using (StreamReader sr = new StreamReader(ldsFileName)) { ldsContents = sr.ReadToEnd(); } // Make backup of language file, if it doesn't exist. if (!File.Exists(ldsFileName + ".bak")) File.Copy(ldsFileName, ldsFileName + ".bak"); // REVIEW: Best way to handle if the file cannot be copied? fileWriterLDS.Open(ldsFileName); UpdateLdsContents(ldsContents, normalStyle, ws, fileWriterLDS); } catch { return false; } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Saves the ssf file. /// </summary> /// <param name="format">the prefix, scheme, suffix, extension</param> /// <param name="sShortName">The short name of the Paratext project</param> /// <param name="styleSheetFile">The style sheet file.</param> /// <param name="projPath">The path where the project is located</param> /// <param name="writer">The file writer.</param> /// <param name="ws">The HVO of the writing system for the current export.</param> /// ------------------------------------------------------------------------------------ public void SaveSsfFile(FileNameFormat format, string sShortName, string styleSheetFile, string projPath, FileWriter writer, int ws) { ComputeSettings(format, projPath, ws); writer.WriteLine("<ScriptureText>"); writer.WriteLine("<BooksPresent>" + BooksPresent + "</BooksPresent>"); writer.WriteLine("<Copyright></Copyright>"); writer.WriteLine("<Directory>" + m_projPath + "</Directory>"); writer.WriteLine("<Editable>T</Editable>"); writer.WriteLine("<Encoding>" + kUnicodeEncoding + "</Encoding>"); writer.WriteLine("<FileNameForm>" + m_fileScheme + "</FileNameForm>"); writer.WriteLine("<FileNamePostPart>" + m_sPostPart + "</FileNamePostPart>"); writer.WriteLine("<FileNamePrePart>" + m_sPrePart + "</FileNamePrePart>"); writer.WriteLine("<FullName>" + m_cache.ProjectId.Name + "</FullName>"); writer.WriteLine("<Language>" + m_wsName + "</Language>"); writer.WriteLine("<LeftToRight>" + m_LtoR + "</LeftToRight>"); writer.WriteLine("<Name>" + sShortName + "</Name>"); writer.WriteLine("<StyleSheet>" + styleSheetFile + "</StyleSheet>"); writer.WriteLine("<Versification>" + m_versification + "</Versification>"); writer.WriteLine(NamingNode); writer.WriteLine("</ScriptureText>"); }
public void UpdateParatextLdsFile_FileMissing() { FileWriter writer = new FileWriter(); ParatextLdsFileAccessor ldsAccessor = new ParatextLdsFileAccessor(Cache); Assert.IsFalse(ReflectionHelper.GetBoolResult(ldsAccessor, "UpdateLdsFile", "c:\\whatever\\wherever\\whenever\\yeah.lds", new DummyUsfmStyEntry(), Cache.DefaultVernWs, writer)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Writes (creates or updates) a Paratext LDS file. /// </summary> /// <param name="ldsFileName">Name of the LDS file.</param> /// <param name="ws">The writing system which the LDS file describes.</param> /// <param name="normalStyle">The normal style.</param> /// <param name="fileWriterLDS">The file writer used to write the LDS file.</param> /// ------------------------------------------------------------------------------------ private void WriteParatextLdsFile(string ldsFileName, int ws, UsfmStyEntry normalStyle, FileWriter fileWriterLDS) { bool fUpdateSucceeded = false; // If the file describing the writing system exists, update values as needed. if (File.Exists(ldsFileName)) { // Check to see if file is writable if ((File.GetAttributes(ldsFileName) & FileAttributes.ReadOnly) != FileAttributes.ReadOnly) fUpdateSucceeded = UpdateLdsFile(ldsFileName, normalStyle, ws, fileWriterLDS); else return; // leave the existing read-only file unchanged } // If the lds file does not exist, or if there was a problem updating the lds file, // then a new lds file must be created. if (!fUpdateSucceeded) { // Create the LDS file in the settings directory WriteLdsFileContents(ldsFileName, normalStyle, ws, fileWriterLDS); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// writes the contents of the LDS file. /// </summary> /// <param name="ldsFileName">name of the Paratext LDS to be saved.</param> /// <param name="normalStyle">The normal style.</param> /// <param name="ws">The HVO of the writing system for the current export.</param> /// <param name="fileWriterLds">file writer for the Paratext LDS file</param> /// ------------------------------------------------------------------------------------ private void WriteLdsFileContents(string ldsFileName, UsfmStyEntry normalStyle, int ws, FileWriter fileWriterLds) { Debug.Assert(fileWriterLds != null); fileWriterLds.Open(ldsFileName); ComputeSettings(normalStyle, ws); fileWriterLds.WriteLine("[General]"); fileWriterLds.WriteLine("codepage=65001"); fileWriterLds.WriteLine("RTL=" + m_RtoL); fileWriterLds.WriteLine("font=" + m_fontName); fileWriterLds.WriteLine("name=" + m_wsName); fileWriterLds.WriteLine("size=" + m_fontSize); fileWriterLds.WriteLine(string.Empty, true); fileWriterLds.WriteLine("[Checking]"); fileWriterLds.WriteLine(string.Empty, true); fileWriterLds.WriteLine("[Characters]"); fileWriterLds.WriteLine(string.Empty, true); fileWriterLds.WriteLine("[Punctuation]"); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Writes (creates or updates) a Paratext LDS file. /// </summary> /// <param name="ldsFileName">Name of the LDS file.</param> /// <param name="ws">The writing system which the LDS file describes.</param> /// <param name="normalStyle">The normal style.</param> /// ------------------------------------------------------------------------------------ public void WriteParatextLdsFile(string ldsFileName, int ws, UsfmStyEntry normalStyle) { FileWriter fileWriterLDS = new FileWriter(); try { WriteParatextLdsFile(ldsFileName, ws, normalStyle, fileWriterLDS); } finally { fileWriterLDS.Close(); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Updates the lds file which describes the writing system in Paratext. /// </summary> /// <param name="ldsContents">Contents of the existing LDS file.</param> /// <param name="normalStyle">The normal style.</param> /// <param name="ws">The writing system</param> /// <param name="writer">The file writer for the Paratext LDS file</param> /// ------------------------------------------------------------------------------------ public void UpdateLdsContents(string ldsContents, UsfmStyEntry normalStyle, int ws, FileWriter writer) { ComputeSettings(normalStyle, ws); string [] lines = ldsContents.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); // Read lines of text from the file, updating it as necessary. bool fInGeneralSection = false; bool fInOtherSection = false; bool fHasGeneralSection = false; bool fHasCodePage = false; bool fHasFont = false; bool fHasFontSize = false; bool fHasName = false; bool fHasRTL = false; foreach (string line in lines) { if (line.StartsWith("[General]")) { if (fInOtherSection) { fInOtherSection = false; writer.WriteLine(); } fInGeneralSection = true; fHasGeneralSection = true; } else if (line.StartsWith("[")) { if (fInGeneralSection) { WriteGeneralSection(writer, ref fHasCodePage, ref fHasFont, ref fHasFontSize, ref fHasName, ref fHasRTL); fInGeneralSection = false; writer.WriteLine(); } else if (fInOtherSection) writer.WriteLine(); fInOtherSection = true; } if (fInGeneralSection) { string replaceString = string.Empty; // Check line for fields that must be updated if (line.StartsWith("codepage=")) { replaceString = "codepage=65001"; fHasCodePage = true; } else if (line.StartsWith("font=")) { replaceString = "font=" + m_fontName; fHasFont = true; } else if (line.StartsWith("size=")) { replaceString = "size=" + m_fontSize; fHasFontSize = true; } else if (line.StartsWith("name=")) { replaceString = "name=" + m_wsName; fHasName = true; } else if (line.StartsWith("RTL=")) { replaceString = "RTL=" + m_RtoL; fHasRTL = true; } if (replaceString != string.Empty) writer.WriteLine(replaceString); // Add updated line to file contents list else writer.WriteLine(line); // Add line, without changes, to file contents list } else writer.WriteLine(line); } if (!fHasGeneralSection) { if (fInOtherSection) { fInOtherSection = false; writer.WriteLine(); } // General section not found. Write it. writer.WriteLine("[General]"); } WriteGeneralSection(writer, ref fHasCodePage, ref fHasFont, ref fHasFontSize, ref fHasName, ref fHasRTL); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Dispose of unmanaged resources hidden in member variables. /// </summary> /// <param name="fDisposing">if set to <c>true</c> called from Dispose() method. In this /// case it is safe to access our managed member variables. If set to <c>false</c> we /// shouldn't access any managed objects because they might have been disposed already. /// </param> /// ------------------------------------------------------------------------------------ public virtual void Dispose(bool fDisposing) { if (m_isDisposed) { Debug.Assert(m_cpe == null); return; } if (fDisposing) { // dispose managed objects if (m_file != null) m_file.Dispose(); if (m_fileSty != null) m_fileSty.Dispose(); } m_file = null; m_fileSty = null; if (m_cpe != null) { if (Marshal.IsComObject(m_cpe)) Marshal.ReleaseComObject(m_cpe); m_cpe = null; } m_isDisposed = true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="ExportUsfm"/> class. /// </summary> /// <param name="cache">FDO cache to use for export</param> /// <param name="filter">book filter to determine which books to export</param> /// <param name="outputFile">File name or folder to export to</param> /// <param name="app">The application.</param> /// ------------------------------------------------------------------------------------ public ExportUsfm(FdoCache cache, FilteredScrBooks filter, string outputFile, IApp app) { m_outputSpec = outputFile; m_file = new FileWriter(); m_cache = cache; m_bookFilter = filter; m_app = app; m_scr = cache.LangProject.TranslatedScriptureOA; // By default, only the default analysis writing system will be included in the // requested set of back translations. m_defaultAnalWS = m_cache.DefaultAnalWs; m_icuLocales = new[] { m_cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem.IcuLocale }; // Read the TeStyles.xml file and create a hash table of style name to // USFM markers m_markerMappings = new SortedDictionary<string, string>(); m_footnoteContentMarkers = new List<string>(); m_ParatextSsfFileAccessor = new ParatextSsfFileAccessor(cache, filter); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Closes the file. /// </summary> /// ------------------------------------------------------------------------------------ private void CloseFile() { if (m_file != null) { try { m_file.Close(); } catch { // ignore errors on close } } m_file = new FileWriter(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Dispose of unmanaged resources hidden in member variables. /// </summary> /// <param name="fDisposing">if set to <c>true</c> called from Dispose() method. In this /// case it is safe to access our managed member variables. If set to <c>false</c> we /// shouldn't access any managed objects because they might have been disposed already. /// </param> /// ------------------------------------------------------------------------------------ protected virtual void Dispose(bool fDisposing) { System.Diagnostics.Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); if (m_isDisposed) { Debug.Assert(m_cpe == null); return; } if (fDisposing) { // dispose managed objects if (m_file != null) m_file.Dispose(); if (m_fileSty != null) m_fileSty.Dispose(); } m_file = null; m_fileSty = null; m_cpe = null; m_isDisposed = true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Creates the paratext project files /// </summary> /// ------------------------------------------------------------------------------------ protected void CreateParatextProjectFiles() { if (!Directory.Exists(m_paratextProjFolder)) return; // Couldn't have exported to the Paratext project folder, so don't want to save settings if (!m_outputSpec.StartsWith(m_paratextProjFolder)) return; // export wasn't done to the Paratext project folder, don't write settings files int ws = m_exportScripture || m_nonInterleavedBtWs < 0 ? m_cache.DefaultVernWs : m_nonInterleavedBtWs; IWritingSystem wsObj = m_cache.ServiceLocator.WritingSystemManager.Get(ws); string wsName = wsObj.DisplayLabel; string lpName = m_cache.ProjectId.Name; string styleFileName = lpName + ".sty"; // Create the STY file in the settings directory m_fileSty = OpenFile(Path.Combine(m_paratextProjFolder, styleFileName)); m_UsfmStyFileAccessor.SaveStyFile(lpName, m_fileSty, m_exportScripture ? m_cache.DefaultVernWs : m_nonInterleavedBtWs); // Create the SSF file in the settings directory if export was done by book. if (m_fileNameFormat != null) { string ldsFileName = Path.Combine(m_paratextProjFolder, wsName + ".lds"); WriteParatextSsfFile(m_paratextProjFolder, styleFileName, ref ldsFileName); WriteParatextLdsFile(ldsFileName, m_exportScripture ? m_cache.DefaultVernWs : m_nonInterleavedBtWs); // As a final step, attempt to copy picture files (internal copies) to the pictures // folder where Paratext expects to find them. CopyPictureFilesForParatext(); CopyVersificationFile(); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Open the file. This is virtual so it can be replaced in testing with an /// in-memory file writer. /// </summary> /// <param name="fileName"></param> /// <returns></returns> /// ------------------------------------------------------------------------------------ protected virtual FileWriter OpenFile(string fileName) { FileWriter writer = new FileWriter(); writer.Open(fileName); return writer; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Serializes this object to the specified writer. /// </summary> /// <param name="ws">HVO of the writing system whose properties should be used for /// figuring out which set of font properties to use (FW allows for overrides based on /// WS). /// </param> /// <param name="writer">The writer.</param> /// ------------------------------------------------------------------------------------ internal void Serialize(int ws, FileWriter writer) { writer.WriteLine(@"\Marker " + P6Marker); if (m_name != null) writer.WriteLine(@"\TEStyleName " + m_name); if (Endmarker != null) writer.WriteLine(@"\Endmarker " + Endmarker); writer.WriteLine(@"\Name " + (P6Name == null ? m_name : P6Name)); if (m_usage != null) writer.WriteLine(@"\Description " + m_usage); if (OccursUnder != null) writer.WriteLine(@"\OccursUnder " + OccursUnder); if (Rank > 0) writer.WriteLine(@"\Rank " + Rank); if (NotRepeatable) writer.WriteLine(@"\NotRepeatable"); writer.WriteLine(@"\TextType " + TextType); writer.WriteLine(@"\TextProperties " + TextProperties); writer.WriteLine(@"\StyleType " + StyleType); FontInfo fontInfo = FontInfoForWs(ws); if (fontInfo.m_italic.ValueIsSet && fontInfo.m_italic.Value) writer.WriteLine(@"\Italic"); if (fontInfo.m_underline.ValueIsSet && fontInfo.m_underline.Value != FwUnderlineType.kuntNone) writer.WriteLine(@"\Underline"); if (fontInfo.m_bold.ValueIsSet && fontInfo.m_bold.Value) writer.WriteLine(@"\Bold"); if (fontInfo.m_superSub.ValueIsSet && fontInfo.m_superSub.Value == FwSuperscriptVal.kssvSuper) writer.WriteLine(@"\Superscript"); if (!fontInfo.m_fontName.IsInherited) // TODO (TE-5185): This isn't good enough - if a char style inherits from another char style that sets a specific font, the derived char style also needs to output that font spec in the sty file because the sty file doesn't handle inheritance. writer.WriteLine(@"\FontName " + RealFontNameForWs(ws)); // Write out the font size, converting it from millipoints to points if (fontInfo.m_fontSize.ValueIsSet) writer.WriteLine(@"\FontSize " + fontInfo.m_fontSize.Value / 1000); if (fontInfo.m_fontColor.ValueIsSet && fontInfo.m_fontColor.Value != Color.Black) writer.WriteLine(@"\Color " + ColorUtil.ConvertColorToBGR(fontInfo.m_fontColor.Value)); if (m_alignment.ValueIsSet) { switch (m_alignment.Value) { case FwTextAlign.ktalCenter: writer.WriteLine(@"\Justification Center"); break; case FwTextAlign.ktalLeading: break; case FwTextAlign.ktalJustify: writer.WriteLine(@"\Justification Both"); break; case FwTextAlign.ktalTrailing: writer.WriteLine(@"\Justification Right"); // "right" really means "trailing" in Paratext break; case FwTextAlign.ktalLeft: if (m_rtl.Value == TriStateBool.triTrue) writer.WriteLine(@"\Justification Right"); // "right" really means "trailing" in Paratext break; case FwTextAlign.ktalRight: if (m_rtl.Value != TriStateBool.triTrue) writer.WriteLine(@"\Justification Right"); // "right" really means "trailing" in Paratext break; } } if (m_firstLineIndent.ValueIsSet && m_firstLineIndent.Value > 0) writer.WriteLine(@"\FirstLineIndent " + (((double)m_firstLineIndent.Value)/72000).ToString("#.000")); if (m_leadingIndent.ValueIsSet && m_leadingIndent.Value > 0) writer.WriteLine(@"\LeftMargin " + (((double)m_leadingIndent.Value)/72000).ToString("#.000")); if (m_trailingIndent.ValueIsSet && m_trailingIndent.Value > 0) writer.WriteLine(@"\RightMargin " + (((double)m_trailingIndent.Value)/72000).ToString("#.000")); if (m_spaceBefore.ValueIsSet && m_spaceBefore.Value > 0) writer.WriteLine(@"\SpaceBefore " + m_spaceBefore.Value / 1000); // convert from millipoints to points if (m_spaceAfter.ValueIsSet && m_spaceAfter.Value > 0) writer.WriteLine(@"\SpaceAfter " + m_spaceAfter.Value / 1000); // convert from millipoints to points if (XmlTag != null) writer.WriteLine(@"\XMLTag " + XmlTag); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Writes the contents of the general section. /// </summary> /// <param name="writer">The writer.</param> /// <param name="fHasCodePage">Indicates whether code page entry has been written.</param> /// <param name="fHasFont">Indicates whether font entry has been written.</param> /// <param name="fHasFontSize">Indicates whether font size entry has been written.</param> /// <param name="fHasName">Indicates whether name entry has been written.</param> /// <param name="fHasRTL">Indicates whether RTL entry has been written.</param> /// ------------------------------------------------------------------------------------ private void WriteGeneralSection(FileWriter writer, ref bool fHasCodePage, ref bool fHasFont, ref bool fHasFontSize, ref bool fHasName, ref bool fHasRTL) { if (!fHasCodePage) { writer.WriteLine("codepage=65001"); fHasCodePage = true; } if (!fHasFont) { writer.WriteLine("font=" + m_fontName); fHasFont = true; } if (!fHasFontSize) { writer.WriteLine("size=" + m_fontSize); fHasFontSize = true; } if (!fHasName) { writer.WriteLine("name=" + m_wsName); fHasName = true; } if (!fHasRTL) { writer.WriteLine("RTL=" + m_RtoL); fHasRTL = true; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Saves the sty file. /// </summary> /// <param name="LangProjectName">Name of the language project.</param> /// <param name="writer">The writer.</param> /// <param name="ws">The HVO of the writing system for the current export.</param> /// ------------------------------------------------------------------------------------ public void SaveStyFile(string LangProjectName, FileWriter writer, int ws) { ConnectStyles(); writer.WriteLine("## Stylesheet for exported TE project " + LangProjectName + " ##"); writer.WriteLine(string.Empty, true); // Write out the style sheet entries foreach (UsfmStyEntry entry in Values) { entry.Serialize(ws, writer); writer.WriteLine(string.Empty, true); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Creates the paratext project files /// </summary> /// ------------------------------------------------------------------------------------ protected void CreateParatextProjectFiles() { SCRIPTUREOBJECTSLib.ISCScriptureText3 paraTextSO; try { paraTextSO = new SCRIPTUREOBJECTSLib.SCScriptureTextClass(); } catch { paraTextSO = null; } if (!Directory.Exists(m_paratextProjFolder)) return; // Couldn't have exported to the Paratext project folder, so don't want to save settings if (!m_outputSpec.StartsWith(m_paratextProjFolder)) return; // export wasn't done to the Paratext project folder, don't write settings files int ws = m_exportScripture || m_nonInterleavedBtWs < 0 ? m_cache.DefaultVernWs : m_nonInterleavedBtWs; LgWritingSystem lgws = new LgWritingSystem(m_cache, ws); string wsName = lgws.Name.UserDefaultWritingSystem; string lpName = m_cache.LangProject.Name.UserDefaultWritingSystem; string styleFileName = lpName + ".sty"; // Create the STY file in the settings directory m_fileSty = OpenFile(Path.Combine(m_paratextProjFolder, styleFileName)); m_UsfmStyFileAccessor.SaveStyFile(lpName, m_fileSty, m_exportScripture ? m_cache.DefaultVernWs : m_nonInterleavedBtWs); // Create the SSF file in the settings directory if export was done by book. if (m_fileNameFormat != null) { string ldsFileName = Path.Combine(m_paratextProjFolder, wsName + ".lds"); WriteParatextSsfFile(paraTextSO, m_paratextProjFolder, styleFileName, ref ldsFileName); WriteParatextLdsFile(ldsFileName, m_exportScripture ? m_cache.DefaultVernWs : m_nonInterleavedBtWs); // As a final step, attempt to copy picture files (internal copies) to the pictures // folder where Paratext expects to find them. CopyPictureFilesForParatext(); CopyVersificationFile(); } }