├── .gitignore ├── LICENSE ├── OneNoteConversionTool.sln ├── OneNoteConversionTool ├── App.config ├── FormatConversion │ ├── ConversionManager.cs │ ├── GenericFormatConverter.cs │ ├── IFormatConverter.cs │ ├── KindercareFormatConverter.cs │ ├── SmsgrFormatConverter.cs │ ├── SmsgrStudentOnlyFormatConverter.cs │ └── SmsgrTrainerOnlyFormatConverter.cs ├── FormatReaders │ ├── EpubReader.cs │ └── PowerPointOpenXml.cs ├── OneNoteConversionForm.Designer.cs ├── OneNoteConversionForm.cs ├── OneNoteConversionForm.resx ├── OneNoteConversionTool.csproj ├── OutputGenerator │ └── OneNoteGenerator.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ └── redX.jpg ├── Utility.cs ├── bin │ └── Debug │ │ └── OneNoteConversionTool.vshost.exe.manifest └── packages.config ├── OneNoteConversionToolSetup └── OneNoteConversionToolSetup.vdproj ├── OneNoteConversionToolUnitTest ├── FormatConversion │ ├── ConversionManagerUnitTest.cs │ ├── GenericFormatConverterUnitTest.cs │ ├── KindercareFormatConverterUnitTest.cs │ ├── MockConversionManager.cs │ ├── MockFormatConverter.cs │ └── SmsgrFormatConverterUnitTest.cs ├── FormatReaders │ ├── EpubReaderUnitTest.cs │ └── PowerPointOpenXmlUnitTest.cs ├── OneNoteConversionToolUnitTest.csproj ├── OutputGenerator │ └── OneNoteGeneratorUnitTest.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources │ ├── EpubSample.epub │ └── SectionSample.pptx ├── Utility.cs └── packages.config ├── README.md └── packages └── epubReader.1.0.0 ├── epubReader.1.0.0.nupkg └── lib └── net40 └── eBdb.EpubReader.dll /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | */[Dd]ebug/ 15 | */[Dd]ebugPublic/ 16 | */[Rr]eleases/ 17 | */[Rr]elease/ 18 | */x64/ 19 | */x86/ 20 | */build/ 21 | */bld/ 22 | */[Bb]in/ 23 | */[Oo]bj/ 24 | 25 | # Visual Studo 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | */[Tt]est[Rr]esult*/ 30 | */[Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | */[Dd]ebugPS/ 38 | */[Rr]eleasePS/ 39 | dlldata.c 40 | 41 | *_i.c 42 | *_p.c 43 | *_i.h 44 | *.ilk 45 | *.meta 46 | *.obj 47 | *.pch 48 | *.pdb 49 | *.pgc 50 | *.pgd 51 | *.rsp 52 | *.sbr 53 | *.tlb 54 | *.tli 55 | *.tlh 56 | *.tmp 57 | *.tmp_proj 58 | *.log 59 | *.vspscc 60 | *.vssscc 61 | .builds 62 | *.pidb 63 | *.svclog 64 | *.scc 65 | 66 | # Chutzpah Test files 67 | _Chutzpah* 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | *.cachefile 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | *.vspx 81 | 82 | # TFS 2012 Local Workspace 83 | $tf/ 84 | 85 | # Guidance Automation Toolkit 86 | *.gpState 87 | 88 | # ReSharper is a .NET coding add-in 89 | _ReSharper*/ 90 | *.[Rr]e[Ss]harper 91 | *.DotSettings.user 92 | 93 | # JustCode is a .NET coding addin-in 94 | .JustCode 95 | 96 | # TeamCity is a build add-in 97 | _TeamCity* 98 | 99 | # DotCover is a Code Coverage Tool 100 | *.dotCover 101 | 102 | # NCrunch 103 | _NCrunch_* 104 | .*crunch*.local.xml 105 | 106 | # MightyMoose 107 | *.mm.* 108 | AutoTest.Net/ 109 | 110 | # Web workbench (sass) 111 | .sass-cache/ 112 | 113 | # Installshield output folder 114 | [Ee]xpress/ 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish/ 128 | 129 | # Publish Web Output 130 | *.[Pp]ublish.xml 131 | *.azurePubxml 132 | # TODO: Comment the next line if you want to checkin your web deploy settings 133 | # but database connection strings (with potential passwords) will be unencrypted 134 | *.pubxml 135 | *.publishproj 136 | 137 | # NuGet Packages 138 | *.nupkg 139 | # The packages folder can be ignored because of Package Restore 140 | **/packages/* 141 | # except build/, which is used as an MSBuild target. 142 | !**/packages/build/ 143 | # Uncomment if necessary however generally it will be regenerated when needed 144 | #!**/packages/repositories.config 145 | 146 | # Windows Azure Build Output 147 | csx/ 148 | *.build.csdef 149 | 150 | # Windows Store app package directory 151 | AppPackages/ 152 | 153 | # Others 154 | *.[Cc]ache 155 | ClientBin/ 156 | [Ss]tyle[Cc]op.* 157 | ~$* 158 | *~ 159 | *.dbmdl 160 | *.dbproj.schemaview 161 | *.pfx 162 | *.publishsettings 163 | node_modules/ 164 | bower_components/ 165 | 166 | # RIA/Silverlight projects 167 | Generated_Code/ 168 | 169 | # Backup & report files from converting an old project file 170 | # to a newer Visual Studio version. Backup files are not needed, 171 | # because we have git ;-) 172 | _UpgradeReport_Files/ 173 | Backup*/ 174 | UpgradeLog*.XML 175 | UpgradeLog*.htm 176 | 177 | # SQL Server files 178 | *.mdf 179 | *.ldf 180 | 181 | # Business Intelligence projects 182 | *.rdl.data 183 | *.bim.layout 184 | *.bim_*.settings 185 | 186 | # Microsoft Fakes 187 | FakesAssemblies/ 188 | 189 | # Node.js Tools for Visual Studio 190 | .ntvs_analysis.dat 191 | 192 | # Visual Studio 6 build log 193 | *.plg 194 | 195 | # Visual Studio 6 workspace options file 196 | *.opt 197 | 198 | # Others 199 | packages 200 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 OneNoteDev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /OneNoteConversionTool.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneNoteConversionTool", "OneNoteConversionTool\OneNoteConversionTool.csproj", "{DF6EFEF6-1D0D-4B64-A425-0A3758F5C251}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneNoteConversionToolUnitTest", "OneNoteConversionToolUnitTest\OneNoteConversionToolUnitTest.csproj", "{86E7B739-1687-4475-B5AD-3989380C204B}" 9 | EndProject 10 | Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "OneNoteConversionToolSetup", "OneNoteConversionToolSetup\OneNoteConversionToolSetup.vdproj", "{6C044E7D-E801-43FF-95B0-2A027AE5C83E}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {DF6EFEF6-1D0D-4B64-A425-0A3758F5C251}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {DF6EFEF6-1D0D-4B64-A425-0A3758F5C251}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {DF6EFEF6-1D0D-4B64-A425-0A3758F5C251}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {DF6EFEF6-1D0D-4B64-A425-0A3758F5C251}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {86E7B739-1687-4475-B5AD-3989380C204B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {86E7B739-1687-4475-B5AD-3989380C204B}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {86E7B739-1687-4475-B5AD-3989380C204B}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {86E7B739-1687-4475-B5AD-3989380C204B}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {6C044E7D-E801-43FF-95B0-2A027AE5C83E}.Debug|Any CPU.ActiveCfg = Debug 27 | {6C044E7D-E801-43FF-95B0-2A027AE5C83E}.Release|Any CPU.ActiveCfg = Release 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /OneNoteConversionTool/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /OneNoteConversionTool/FormatConversion/ConversionManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.IO; 5 | using System.Linq; 6 | 7 | namespace OneNoteConversionTool.FormatConversion 8 | { 9 | /// 10 | /// Handles converting the different input types into OneNote (output) 11 | /// 12 | public class ConversionManager 13 | { 14 | private static Dictionary _supportedConverters; 15 | protected static Dictionary SupportedConverters 16 | { 17 | get 18 | { 19 | //Lazy initialization 20 | if (_supportedConverters == null) 21 | { 22 | _supportedConverters = new Dictionary(); 23 | string inputFormat = ConfigurationManager.AppSettings.Get("InputFormat"); 24 | IFormatConverter converter; 25 | 26 | //Adding generic as supported format 27 | converter = new GenericFormatConverter(); 28 | _supportedConverters.Add(converter.GetSupportedInputFormat(), converter); 29 | 30 | if (inputFormat == "Kindercare" || inputFormat == "All") 31 | { 32 | //Adding Kindercare as supported format 33 | converter = new KindercareFormatConverter(); 34 | _supportedConverters.Add(converter.GetSupportedInputFormat(), converter); 35 | } 36 | 37 | if (inputFormat == "SMSGR" || inputFormat == "All") 38 | { 39 | //Adding SMSGR as supported format 40 | converter = new SmsgrFormatConverter(); 41 | _supportedConverters.Add(converter.GetSupportedInputFormat(), converter); 42 | 43 | //Adding SMSGR for trainer only as supported format 44 | converter = new SmsgrTrainerOnlyFormatConverter(); 45 | _supportedConverters.Add(converter.GetSupportedInputFormat(), converter); 46 | 47 | //Adding SMSGR for student only as supported format 48 | converter = new SmsgrStudentOnlyFormatConverter(); 49 | _supportedConverters.Add(converter.GetSupportedInputFormat(), converter); 50 | } 51 | } 52 | return _supportedConverters; 53 | } 54 | set { _supportedConverters = value; } 55 | } 56 | 57 | /// 58 | /// Returns the list of all supported input formats 59 | /// 60 | /// 61 | public static List GetSupportedFormats() 62 | { 63 | return SupportedConverters.Keys.ToList(); 64 | } 65 | 66 | /// 67 | /// Converts Input using the specified format 68 | /// 69 | /// 70 | /// 71 | /// 72 | public static void ConvertInput(string converterType, string inputPath, string outputDir) 73 | { 74 | IFormatConverter converter; 75 | if (SupportedConverters.TryGetValue(converterType, out converter)) 76 | { 77 | if ((File.GetAttributes(inputPath) & FileAttributes.Directory) == FileAttributes.Directory) 78 | { 79 | ConvertDirectory(converter, inputPath, outputDir); 80 | } 81 | else 82 | { 83 | ConvertFile(converter, inputPath, outputDir); 84 | } 85 | } 86 | else 87 | { 88 | throw new NotSupportedException("Unable to find the converter for this format type."); 89 | } 90 | } 91 | 92 | /// 93 | /// Helper method to iterate through a directory and convert all the files underneath it 94 | /// 95 | /// 96 | /// 97 | /// 98 | private static void ConvertDirectory(IFormatConverter converter, string inputDir, string outputDir) 99 | { 100 | var notSupportedFiles = ConvertDirectoryImpl(converter, inputDir, outputDir); 101 | 102 | if (notSupportedFiles.Count > 0) 103 | { 104 | throw new NotSupportedException(string.Format("The following files were not converted:\n{0}", 105 | string.Join("\n", notSupportedFiles.ToArray()))); 106 | } 107 | } 108 | 109 | /// 110 | /// The internal implementation of the method that goes into the directory and tries to convert all 111 | /// files underneath it recursively. 112 | /// 113 | /// 114 | /// 115 | /// 116 | /// 117 | private static ICollection ConvertDirectoryImpl(IFormatConverter converter, string inputDir, string outputDir) 118 | { 119 | var files = Directory.GetFiles(inputDir); 120 | var dirs = Directory.GetDirectories(inputDir); 121 | var notSupportedFiles = new List(); 122 | 123 | // Iterate through all files in this directory 124 | foreach (var file in files) 125 | { 126 | try 127 | { 128 | ConvertFile(converter, file, outputDir); 129 | } 130 | catch (NotSupportedException) 131 | { 132 | //Do not block the conversion process, but keep the list of files unable to be converted 133 | notSupportedFiles.Add(file); 134 | } 135 | } 136 | 137 | // Iterate through all directories in this directory 138 | foreach (var dir in dirs) 139 | { 140 | notSupportedFiles.AddRange(ConvertDirectoryImpl(converter, dir, outputDir)); 141 | } 142 | 143 | return notSupportedFiles; 144 | } 145 | 146 | /// 147 | /// Converts a single file into a section in OneNote notebook 148 | /// 149 | /// 150 | /// 151 | /// 152 | private static void ConvertFile(IFormatConverter converter, string inputFile, string outputDir) 153 | { 154 | var file = new FileInfo(inputFile); 155 | if (Utility.WordSupportedExtenssions.Any( 156 | ext => ext.Equals(file.Extension, StringComparison.InvariantCultureIgnoreCase))) 157 | { 158 | converter.ConvertWordToOneNote(inputFile, outputDir); 159 | } 160 | else if (Utility.PowerPointSupportedExtenssions.Any( 161 | ext => ext.Equals(file.Extension, StringComparison.InvariantCultureIgnoreCase))) 162 | { 163 | converter.ConvertPowerPointToOneNote(inputFile, outputDir); 164 | } 165 | else if (Utility.PdfSupportedExtenssions.Any( 166 | ext => ext.Equals(file.Extension, StringComparison.InvariantCultureIgnoreCase))) 167 | { 168 | converter.ConvertPdfToOneNote(inputFile, outputDir); 169 | } 170 | else if (Utility.EpubSupportedExtenssions.Any( 171 | ext => ext.Equals(file.Extension, StringComparison.InvariantCultureIgnoreCase))) 172 | { 173 | converter.ConvertEpubToOneNote(inputFile, outputDir); 174 | } 175 | else if (Utility.InDesignSupportedExtenssions.Any( 176 | ext => ext.Equals(file.Extension, StringComparison.InvariantCultureIgnoreCase))) 177 | { 178 | converter.ConvertInDesignToOneNote(inputFile, outputDir); 179 | } 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /OneNoteConversionTool/FormatConversion/IFormatConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OneNoteConversionTool.FormatConversion 8 | { 9 | public interface IFormatConverter 10 | { 11 | /// 12 | /// Converts the Word document input file into OneNote 13 | /// 14 | /// 15 | /// 16 | bool ConvertWordToOneNote(string inputFile, string outputDir); 17 | 18 | /// 19 | /// Converts the PDF document input file into OneNote 20 | /// 21 | /// 22 | /// 23 | bool ConvertPdfToOneNote(string inputFile, string outputDir); 24 | 25 | /// 26 | /// Converts the PowerPoint document input file into OneNote 27 | /// 28 | /// 29 | /// 30 | bool ConvertPowerPointToOneNote(string inputFile, string outputDir); 31 | 32 | /// 33 | /// Converts the InDesign document input file into OneNote 34 | /// 35 | /// 36 | /// 37 | /// 38 | bool ConvertInDesignToOneNote(string inputFile, string outputDir); 39 | 40 | 41 | /// 42 | /// Converts the ePub document input file into OneNote 43 | /// 44 | /// 45 | /// 46 | /// 47 | bool ConvertEpubToOneNote(string inputFile, string outputDir); 48 | 49 | /// 50 | /// Returns the name of the input format that this IFormatConverter supports 51 | /// 52 | /// 53 | string GetSupportedInputFormat(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /OneNoteConversionTool/FormatConversion/KindercareFormatConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using HtmlAgilityPack; 7 | using OneNoteConversionTool.OutputGenerator; 8 | using HtmlDocument = HtmlAgilityPack.HtmlDocument; 9 | 10 | namespace OneNoteConversionTool.FormatConversion 11 | { 12 | /// 13 | /// Converter that accepts Kindercare format 14 | /// 15 | public class KindercareFormatConverter : GenericFormatConverter 16 | { 17 | private const string InputFormat = "Kindercare"; 18 | 19 | public override string GetSupportedInputFormat() 20 | { 21 | return InputFormat; 22 | } 23 | 24 | /// 25 | /// Converts Html file into OneNote Section of Pages 26 | /// 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// 33 | protected override bool ConvertHtmlToOneNote(string inputFile, string originalPicFolder, string auxInputFolder, OneNoteGenerator onGenerator, string sectionId) 34 | { 35 | var retVal = false; 36 | 37 | try 38 | { 39 | string htmlContent; 40 | using (var sr = new StreamReader(inputFile, Encoding.Default)) 41 | { 42 | htmlContent = sr.ReadToEnd(); 43 | } 44 | 45 | var doc = new HtmlDocument(); 46 | doc.LoadHtml(htmlContent); 47 | 48 | var content = doc.DocumentNode; 49 | 50 | //outer html contains format information 51 | var htmlBox = doc.DocumentNode; 52 | //list of onenote page Id 53 | var pageIdList = new List(); 54 | //list of onenote page/subpage name 55 | var pageNameList = new List(); 56 | //separate the whole doc into pages 57 | var pages = SeparatePages(content) as List>; 58 | //get chapter names from table contents 59 | var chapterNameList = new List(); 60 | 61 | //may produce problem by calling first() 62 | //maybe empty page with pageNameList[0] = null, fix later 63 | var tableContent = pages.FirstOrDefault(); 64 | if (tableContent != null) 65 | { 66 | foreach (var node in tableContent) 67 | { 68 | chapterNameList.Add(node.InnerText.Replace("\r\n", " ").Trim()); 69 | } 70 | } 71 | 72 | //store errors occurred during conversion 73 | var errorList = new List>(); 74 | 75 | //print pages to onenote 76 | foreach (var page in pages) 77 | { 78 | var pageTitle = GetPageTitle(page); 79 | var pageId = onGenerator.CreatePage(pageTitle, sectionId); 80 | 81 | var errorInfo = new Dictionary(); 82 | var pageContent = GeneratePageContent(htmlBox, page, originalPicFolder, auxInputFolder, errorInfo); 83 | onGenerator.AddPageContentAsHtmlBlock(pageId, pageContent); 84 | 85 | pageIdList.Add(pageId); 86 | pageNameList.Add(pageTitle); 87 | 88 | if (errorInfo.Count > 0) 89 | { 90 | errorInfo.Add(InfoType.Id, pageId); 91 | errorInfo.Add(InfoType.Title, pageTitle); 92 | errorList.Add(errorInfo); 93 | } 94 | } 95 | if (errorList.Count > 0) 96 | { 97 | CreateErrorPage(onGenerator, sectionId, errorList); 98 | } 99 | //set some pages as subpages according to observed rules 100 | var lastSeenChapterName = String.Empty; 101 | for (int i = 0; i < pageIdList.Count; i++) 102 | { 103 | var pageId = pageIdList[i]; 104 | var name = pageNameList[i]; 105 | //check if the page name is a chapter name (a substring of table content items) 106 | var isChapterName = chapterNameList.Any(x => x.Contains(name)); 107 | 108 | bool isSubpage = !isChapterName && name != lastSeenChapterName; 109 | 110 | //if it is a new chapter name, set it as a page 111 | //if it is not a chapter name, but it is the first of consecutive same name pages, set it as a page 112 | if (isChapterName == false 113 | && i > 0 && name != pageNameList[i - 1] 114 | && i < pageNameList.Count && name == pageNameList[i + 1]) 115 | { 116 | isSubpage = false; 117 | } 118 | 119 | if (isSubpage) 120 | { 121 | onGenerator.SetSubPage(sectionId, pageId); 122 | } 123 | if (isChapterName) 124 | { 125 | lastSeenChapterName = name; 126 | } 127 | } 128 | retVal = true; 129 | } 130 | catch (Exception e) 131 | { 132 | Console.WriteLine(e.Message); 133 | retVal = false; 134 | } 135 | 136 | return retVal; 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /OneNoteConversionTool/FormatConversion/SmsgrFormatConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using OneNoteConversionTool.FormatReaders; 4 | using OneNoteConversionTool.OutputGenerator; 5 | 6 | namespace OneNoteConversionTool.FormatConversion 7 | { 8 | /// 9 | /// Converter that accepts SMSGR Format 10 | /// 11 | public class SmsgrFormatConverter : GenericFormatConverter 12 | { 13 | private const string InputFormat = "OneNote Courseware Output"; 14 | private const string TrainerNotebook = "Trainer Notebook"; 15 | private const string StudentNotebook = "Student Notebook"; 16 | private const string TrainerNotesTitle = "Trainer Notes"; 17 | private const string StudentNotesTitle = "Student Notes"; 18 | 19 | 20 | /// 21 | /// Returns the name of the input format that this IFormatConverter supports 22 | /// 23 | /// 24 | public override string GetSupportedInputFormat() 25 | { 26 | return InputFormat; 27 | } 28 | 29 | /// 30 | /// Converts PowerPoint presentan to OneNote while converting the sections in power point to main pages, and slides to sub pages 31 | /// It creates two notebooks, one for the Trainer and one for the student 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | protected override void ConvertPowerPointToOneNote(PowerPointOpenXml pptOpenXml, string imgsPath, OneNoteGenerator note, 38 | string sectionName) 39 | { 40 | string trainerNotebookId = String.Empty; 41 | string trainerSectionId = String.Empty; 42 | if (IncludeTrainerNotebook()) 43 | { 44 | // Create the student notebook 45 | trainerNotebookId = note.CreateNotebook(TrainerNotebook); 46 | trainerSectionId = note.CreateSection(sectionName, trainerNotebookId); 47 | } 48 | 49 | string studentNotebookId = String.Empty; 50 | string studentSectionId = String.Empty; 51 | if (IncludeStudentNotebook()) 52 | { 53 | // Create the student notebook 54 | studentNotebookId = note.CreateNotebook(StudentNotebook); 55 | studentSectionId = note.CreateSection(sectionName, studentNotebookId); 56 | } 57 | 58 | if (pptOpenXml.HasSections()) 59 | { 60 | List sectionNames = pptOpenXml.GetSectionNames(); 61 | List> slidesInSections = pptOpenXml.GetSlidesInSections(); 62 | 63 | if (IncludeTrainerNotebook()) 64 | ConvertPowerPointWithSectionsToOneNote(pptOpenXml, imgsPath, note, trainerSectionId, sectionNames, slidesInSections, true); 65 | 66 | if (IncludeStudentNotebook()) 67 | ConvertPowerPointWithSectionsToOneNote(pptOpenXml, imgsPath, note, studentSectionId, sectionNames, slidesInSections, false); 68 | } 69 | else 70 | { 71 | if (IncludeTrainerNotebook()) 72 | ConvertPowerPointWithoutSectionsToOneNote(pptOpenXml, imgsPath, note, trainerSectionId, true); 73 | 74 | if (IncludeStudentNotebook()) 75 | ConvertPowerPointWithoutSectionsToOneNote(pptOpenXml, imgsPath, note, studentSectionId, false); 76 | } 77 | } 78 | 79 | /// 80 | /// Gets whether the trainer notebook should be created or not 81 | /// 82 | /// 83 | protected virtual bool IncludeTrainerNotebook() 84 | { 85 | return true; 86 | } 87 | 88 | /// 89 | /// Gets whether the trainer notebook should be created or not 90 | /// 91 | /// 92 | protected virtual bool IncludeStudentNotebook() 93 | { 94 | return true; 95 | } 96 | 97 | #region Helper Methods 98 | /// 99 | /// Helper method to include the common code between the trainer and the student create notebook when converting 100 | /// Power Point files that have sections 101 | /// 102 | /// 103 | /// 104 | /// 105 | /// 106 | /// 107 | /// 108 | /// 109 | private void ConvertPowerPointWithSectionsToOneNote(PowerPointOpenXml pptOpenXml, string imgsPath, OneNoteGenerator note, 110 | string sectionId, List sectionNames, List> slidesInSections, bool isTrainer) 111 | { 112 | var pptSectionsPageIds = new List(); 113 | 114 | for (int i = 0; i < sectionNames.Count; i++) 115 | { 116 | string pptSectionPageId = note.CreatePage(sectionNames[i], sectionId); 117 | foreach (var slideNumber in slidesInSections[i]) 118 | { 119 | string pageId; 120 | if (isTrainer) 121 | { 122 | pageId = InsertPowerPointSlideInOneNote(slideNumber, pptOpenXml, imgsPath, note, sectionId, 123 | true, StudentNotesTitle, true, TrainerNotesTitle); 124 | 125 | } 126 | else 127 | { 128 | pageId = InsertPowerPointSlideInOneNote(slideNumber, pptOpenXml, imgsPath, note, sectionId, 129 | true, StudentNotesTitle, false); 130 | } 131 | if (!pageId.Equals(String.Empty)) 132 | { 133 | note.SetSubPage(sectionId, pageId); 134 | note.SetShowDate(pageId, false); 135 | note.SetShowTime(pageId, false); 136 | } 137 | } 138 | pptSectionsPageIds.Add(pptSectionPageId); 139 | } 140 | 141 | string tocPageId = note.CreateTableOfContentPage(sectionId); 142 | note.SetShowDate(tocPageId, false); 143 | note.SetShowTime(tocPageId, false); 144 | 145 | foreach (var pptSectionPageId in pptSectionsPageIds) 146 | { 147 | note.SetCollapsePage(pptSectionPageId); 148 | note.SetShowDate(pptSectionPageId, false); 149 | note.SetShowTime(pptSectionPageId, false); 150 | } 151 | } 152 | 153 | /// 154 | /// Helper method to include the common code between the trainer and the student create notebook when converting 155 | /// Power Point files that doesn't have sections 156 | /// 157 | /// 158 | /// 159 | /// 160 | /// 161 | /// 162 | private void ConvertPowerPointWithoutSectionsToOneNote(PowerPointOpenXml pptOpenXml, string imgsPath, OneNoteGenerator note, 163 | string sectionId, bool isTrainer) 164 | { 165 | for (var i = 1; i <= pptOpenXml.NumberOfSlides(); i++) 166 | { 167 | string pageId; 168 | if (isTrainer) 169 | { 170 | pageId = InsertPowerPointSlideInOneNote(i, pptOpenXml, imgsPath, note, sectionId, 171 | true, StudentNotesTitle, true, TrainerNotesTitle); 172 | } 173 | else 174 | { 175 | pageId = InsertPowerPointSlideInOneNote(i, pptOpenXml, imgsPath, note, sectionId, 176 | true, StudentNotesTitle, false); 177 | } 178 | if (!pageId.Equals(String.Empty)) 179 | { 180 | note.SetShowDate(pageId, false); 181 | note.SetShowTime(pageId, false); 182 | } 183 | } 184 | string tocPageId = note.CreateTableOfContentPage(sectionId); 185 | note.SetShowDate(tocPageId, false); 186 | note.SetShowTime(tocPageId, false); 187 | } 188 | #endregion 189 | } 190 | } -------------------------------------------------------------------------------- /OneNoteConversionTool/FormatConversion/SmsgrStudentOnlyFormatConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OneNoteConversionTool.FormatConversion 8 | { 9 | class SmsgrStudentOnlyFormatConverter : SmsgrFormatConverter 10 | { 11 | private const string InputFormat = "OneNote Courseware Output - Student Only"; 12 | 13 | /// 14 | /// Returns the name of the input format that this IFormatConverter supports 15 | /// 16 | /// 17 | public override string GetSupportedInputFormat() 18 | { 19 | return InputFormat; 20 | } 21 | 22 | /// 23 | /// Gets whether the trainer notebook should be created or not 24 | /// 25 | /// 26 | protected override bool IncludeTrainerNotebook() 27 | { 28 | return false; 29 | } 30 | 31 | /// 32 | /// Gets whether the trainer notebook should be created or not 33 | /// 34 | /// 35 | protected override bool IncludeStudentNotebook() 36 | { 37 | return true; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /OneNoteConversionTool/FormatConversion/SmsgrTrainerOnlyFormatConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OneNoteConversionTool.FormatConversion 8 | { 9 | class SmsgrTrainerOnlyFormatConverter : SmsgrFormatConverter 10 | { 11 | private const string InputFormat = "OneNote Courseware Output - Trainer Only"; 12 | 13 | /// 14 | /// Returns the name of the input format that this IFormatConverter supports 15 | /// 16 | /// 17 | public override string GetSupportedInputFormat() 18 | { 19 | return InputFormat; 20 | } 21 | 22 | /// 23 | /// Gets whether the trainer notebook should be created or not 24 | /// 25 | /// 26 | protected override bool IncludeTrainerNotebook() 27 | { 28 | return true; 29 | } 30 | 31 | /// 32 | /// Gets whether the trainer notebook should be created or not 33 | /// 34 | /// 35 | protected override bool IncludeStudentNotebook() 36 | { 37 | return false; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /OneNoteConversionTool/FormatReaders/EpubReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Globalization; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Xml; 8 | using eBdb.EpubReader; 9 | using HtmlAgilityPack; 10 | using Ionic.Zip; 11 | 12 | namespace OneNoteConversionTool.FormatReaders 13 | { 14 | /// 15 | /// Obtains data from epub file 16 | /// 17 | public class EpubReader 18 | { 19 | #region Global Variables 20 | private const string MathMlNameSpace = "http://www.w3.org/1998/Math/MathML"; 21 | private const string MathMlOutline = ""; 22 | 23 | private const double MaxWidth = 960; 24 | 25 | private readonly Epub _mEpub; 26 | private readonly string _mFilePath; 27 | private readonly string _mEpubDir; 28 | private readonly string _mContentDir; 29 | #endregion 30 | 31 | public EpubReader(string filePath, string outputDir) 32 | { 33 | try 34 | { 35 | _mEpub = new Epub(filePath); 36 | } 37 | catch (Exception e) 38 | { 39 | _mEpub = null; 40 | Console.WriteLine("Error in EpubReader: _mEpub couldn't be initialized."); 41 | Console.WriteLine(e.Message); 42 | } 43 | _mFilePath = filePath; 44 | 45 | string epubExtractDir = Directory.Exists(Path.Combine(outputDir, "Epub Extracted Files")) 46 | ? Path.Combine(outputDir, "Epub Extracted Files") 47 | : Utility.CreateDirectory(Path.Combine(outputDir, "Epub Extracted Files")); 48 | _mEpubDir = Utility.CreateDirectory(Utility.NewFolderPath(epubExtractDir, Path.GetFileNameWithoutExtension(filePath))); 49 | ZipFile.Read(filePath).ExtractAll(_mEpubDir); 50 | 51 | _mContentDir = Path.GetDirectoryName(GetOpfFilePath()); 52 | } 53 | 54 | #region Public Methods 55 | /// 56 | /// Gets the title of the epub file 57 | /// 58 | /// 59 | public string GetTitle() 60 | { 61 | return _mEpub != null && _mEpub.Title != null && _mEpub.Title.Count > 0 62 | ? _mEpub.Title[0].Trim() 63 | : Path.GetFileNameWithoutExtension(_mFilePath); 64 | } 65 | 66 | /// 67 | /// Gets the title of each page 68 | /// 69 | /// 70 | public List GetPageTitles() 71 | { 72 | var pageTitles = new List(); 73 | 74 | // Get the title of each page 75 | foreach (var pagePath in GetPagePaths()) 76 | { 77 | var doc = new HtmlDocument(); 78 | doc.Load(pagePath); 79 | 80 | HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//h1") ?? doc.DocumentNode.SelectSingleNode("//title"); 81 | 82 | pageTitles.Add(titleNode != null ? Utility.UnescapeXml(titleNode.InnerText.Trim()) : String.Empty); 83 | } 84 | 85 | return pageTitles; 86 | } 87 | 88 | /// 89 | /// Get the file paths of all pages 90 | /// 91 | /// 92 | public List GetPagePaths() 93 | { 94 | // Get the paths of each page using _mEpub if it is not null 95 | if (_mEpub != null) 96 | { 97 | return (from string htmlPath in _mEpub.Content.Keys 98 | select Path.GetFullPath(Path.Combine(_mContentDir, htmlPath))).ToList(); 99 | } 100 | 101 | var pagePaths = new List(); 102 | 103 | // Get the opf path and ensure that it exists 104 | string opfPath = GetOpfFilePath(); 105 | if (opfPath.Equals(String.Empty)) 106 | { 107 | return pagePaths; 108 | } 109 | 110 | // Load the opf file 111 | var xOpfDoc = new XmlDocument(); 112 | xOpfDoc.Load(opfPath); 113 | 114 | // Get the spine data 115 | XmlNodeList xNodes = xOpfDoc.SelectNodes("//*"); 116 | if (xNodes == null) 117 | { 118 | return pagePaths; 119 | } 120 | 121 | List xItemRefNodes = (from XmlNode xNode in xNodes 122 | where xNode.Name.Contains("itemref") 123 | select xNode).ToList(); 124 | foreach (XmlNode xItemRefNode in xItemRefNodes) 125 | { 126 | if (xItemRefNode.Attributes == null || xItemRefNode.Attributes["idref"] == null) 127 | { 128 | pagePaths.Add(String.Empty); 129 | continue; 130 | } 131 | string idref = xItemRefNode.Attributes["idref"].Value; 132 | string xPath = String.Format("//*[@id=\"{0}\"]", idref); 133 | XmlNode node = xOpfDoc.SelectSingleNode(xPath); 134 | 135 | pagePaths.Add(node == null || node.Attributes == null || node.Attributes["href"] == null 136 | ? String.Empty 137 | : Path.GetFullPath(Path.Combine(_mContentDir, node.Attributes["href"].Value))); 138 | } 139 | 140 | return pagePaths; 141 | } 142 | 143 | /// 144 | /// Gets the html code for each page 145 | /// 146 | /// 147 | public List GetPagesAsHtmlDocuments() 148 | { 149 | var pagesAsHtml = new List(); 150 | 151 | // Get the pages as html 152 | foreach (string pagePath in GetPagePaths()) 153 | { 154 | var htmlDoc = new HtmlDocument(); 155 | htmlDoc.Load(pagePath); 156 | 157 | // Remove Title 158 | HtmlNode titleNode = htmlDoc.DocumentNode.SelectSingleNode("//h1"); 159 | if (titleNode != null) 160 | { 161 | titleNode.Remove(); 162 | } 163 | 164 | // Remove from Script and style nodes 165 | HtmlNodeCollection scriptAndStyleNodes = htmlDoc.DocumentNode.SelectNodes("//script | //style"); 166 | if (scriptAndStyleNodes != null) 167 | { 168 | foreach (var node in scriptAndStyleNodes) 169 | { 170 | node.InnerHtml = node.InnerHtml.Replace("", ""); 171 | } 172 | } 173 | 174 | // Convert MathML 175 | ConvertMathMl(htmlDoc); 176 | 177 | // Replace relative paths in links with full paths 178 | UseFullPathForLinks(htmlDoc, pagePath); 179 | 180 | // Ensure that images have their full dimenssions (up to max width of 960 px) 181 | AddImageDimenssionsToHtml(htmlDoc); 182 | 183 | pagesAsHtml.Add(htmlDoc); 184 | } 185 | 186 | return pagesAsHtml; 187 | } 188 | 189 | /// 190 | /// Gets the level of each page as dictionary where the key in the dictionary is the 191 | /// full path of the xhtml page 192 | /// 193 | /// 194 | public Dictionary GetPagesLevel() 195 | { 196 | var pagesLevel = new Dictionary(); 197 | 198 | // Gets the opf package document 199 | var opfDoc = new XmlDocument(); 200 | opfDoc.Load(GetOpfFilePath()); 201 | if (opfDoc.DocumentElement == null) 202 | { 203 | return pagesLevel; 204 | } 205 | 206 | // Gets the Navigation page 207 | XmlNode xmlNavNode = opfDoc.DocumentElement.SelectSingleNode("//*[@properties=\"nav\"]"); 208 | if (xmlNavNode == null || xmlNavNode.Attributes == null || xmlNavNode.Attributes["href"] == null) 209 | { 210 | return pagesLevel; 211 | } 212 | 213 | // Load the navigation page as HtmlDocument 214 | var navDoc = new HtmlDocument(); 215 | string navPath = Path.Combine(_mContentDir, xmlNavNode.Attributes["href"].Value); 216 | navDoc.Load(navPath); 217 | 218 | // Gets the directory of all the xhtml files 219 | string htmlDir = Path.GetDirectoryName(navPath); 220 | if (htmlDir == null) 221 | { 222 | return pagesLevel; 223 | } 224 | 225 | // Gets the page levels 226 | HtmlNodeCollection nodes = navDoc.DocumentNode.SelectNodes("//*[@href]"); 227 | foreach (var node in nodes) 228 | { 229 | if (!File.Exists(Path.Combine(htmlDir, node.Attributes["href"].Value))) 230 | { 231 | continue; 232 | } 233 | string filePath = Path.GetFullPath(Path.Combine(htmlDir, node.Attributes["href"].Value)); 234 | int pageLevel = node.AncestorsAndSelf().Count(e => e.Name.Equals("li")); 235 | if (!pagesLevel.ContainsKey(filePath)) 236 | { 237 | pagesLevel.Add(filePath, pageLevel); 238 | } 239 | } 240 | 241 | return pagesLevel; 242 | } 243 | #endregion 244 | 245 | #region Private Methods 246 | /// 247 | /// Get the Opf file path 248 | /// 249 | /// 250 | private string GetOpfFilePath() 251 | { 252 | string containerXmlPath = Path.Combine(_mEpubDir, "meta-inf\\container.xml"); 253 | 254 | XmlDocument xDoc = new XmlDocument(); 255 | xDoc.Load(containerXmlPath); 256 | 257 | XmlNode node = xDoc.SelectSingleNode("//*[@media-type = \"application/oebps-package+xml\"]"); 258 | 259 | return node != null && node.Attributes != null && node.Attributes["full-path"] != null 260 | ? Path.Combine(_mEpubDir, node.Attributes["full-path"].Value) 261 | : String.Empty; 262 | } 263 | 264 | /// 265 | /// Converts the MathML blocks to be readable by OneNote 266 | /// 267 | /// 268 | private void ConvertMathMl(HtmlDocument htmlDoc) 269 | { 270 | HtmlNodeCollection mathNodes = htmlDoc.DocumentNode.SelectNodes("//math"); 271 | if (mathNodes == null) 272 | { 273 | return; 274 | } 275 | 276 | foreach (var mathNode in mathNodes.ToList()) 277 | { 278 | mathNode.Attributes.RemoveAll(); 279 | HtmlAttribute mathMlNamespaceAttr = htmlDoc.CreateAttribute("xmlns:mml", MathMlNameSpace); 280 | mathNode.Attributes.Add(mathMlNamespaceAttr); 281 | 282 | foreach (var node in mathNode.DescendantsAndSelf()) 283 | { 284 | node.Name = "mml:" + node.Name; 285 | } 286 | 287 | string newMathMlString = String.Format(MathMlOutline, mathNode.OuterHtml); 288 | HtmlCommentNode newMathNode = htmlDoc.CreateComment(newMathMlString); 289 | mathNode.ParentNode.ReplaceChild(newMathNode, mathNode); 290 | } 291 | } 292 | 293 | /// 294 | /// Replace the relative paths with full paths 295 | /// 296 | /// 297 | /// 298 | private void UseFullPathForLinks(HtmlDocument htmlDoc, string htmlPath) 299 | { 300 | HtmlNodeCollection links = htmlDoc.DocumentNode.SelectNodes("//*[@background or @lowsrc or @src or @href]"); 301 | if (links == null) 302 | { 303 | return; 304 | } 305 | 306 | // Get the directory where the html path exists 307 | string htmlDir = Path.GetDirectoryName(htmlPath); 308 | if (htmlDir == null) 309 | { 310 | return; 311 | } 312 | 313 | foreach (var link in links) 314 | { 315 | // Background 316 | if (link.Attributes["background"] != null) 317 | { 318 | link.Attributes["background"].Value = Path.GetFullPath(Path.Combine(htmlDir, link.Attributes["background"].Value)); 319 | } 320 | 321 | // Lowsrc 322 | if (link.Attributes["lowsrc"] != null) 323 | { 324 | link.Attributes["lowsrc"].Value = Path.GetFullPath(Path.Combine(htmlDir, link.Attributes["lowsrc"].Value)); 325 | } 326 | 327 | // src 328 | if (link.Attributes["src"] != null) 329 | { 330 | link.Attributes["src"].Value = Path.GetFullPath(Path.Combine(htmlDir, link.Attributes["src"].Value)); 331 | } 332 | 333 | // href 334 | if (link.Attributes["href"] != null && File.Exists(Path.Combine(htmlDir, link.Attributes["href"].Value))) 335 | { 336 | link.Attributes["href"].Value = Path.GetFullPath(Path.Combine(htmlDir, link.Attributes["href"].Value)); 337 | } 338 | else if (link.Attributes["href"] != null && link.Attributes["href"].Value.Contains('#')) 339 | { 340 | int indexOfHash = link.Attributes["href"].Value.LastIndexOf('#'); 341 | string relativePath = link.Attributes["href"].Value.Substring(0, indexOfHash); 342 | string fullPath = File.Exists(Path.Combine(htmlDir, relativePath)) 343 | ? Path.GetFullPath(Path.Combine(htmlDir, relativePath)) 344 | : link.Attributes["href"].Value; 345 | link.Attributes["href"].Value = indexOfHash == 0 ? htmlPath : fullPath; 346 | } 347 | } 348 | } 349 | 350 | /// 351 | /// Add the dimenssions of images to the Html ensuring that the images has max width of 960 pixels 352 | /// 353 | /// 354 | private void AddImageDimenssionsToHtml(HtmlDocument htmlDoc) 355 | { 356 | HtmlNodeCollection imgNodes = htmlDoc.DocumentNode.SelectNodes("//img[@src]"); 357 | if (imgNodes == null) 358 | { 359 | return; 360 | } 361 | foreach (HtmlNode imgNode in imgNodes) 362 | { 363 | Image img; 364 | try 365 | { 366 | img = Image.FromFile(imgNode.Attributes["src"].Value); 367 | } 368 | catch (Exception) 369 | { 370 | Console.WriteLine("Error in AddImageDimenssionsToHtml: No image found at {0}", imgNode.Attributes["src"].Value); 371 | continue; 372 | } 373 | 374 | HtmlAttribute heightAttr = htmlDoc.CreateAttribute("height"); 375 | HtmlAttribute widthAttr = htmlDoc.CreateAttribute("width"); 376 | if (img.Width > MaxWidth) 377 | { 378 | heightAttr.Value = ((img.Height * MaxWidth) / (img.Width)).ToString(CultureInfo.CurrentCulture); 379 | widthAttr.Value = MaxWidth.ToString(CultureInfo.CurrentCulture); 380 | } 381 | else 382 | { 383 | heightAttr.Value = img.Height.ToString(); 384 | widthAttr.Value = img.Width.ToString(); 385 | } 386 | img.Dispose(); 387 | 388 | imgNode.Attributes.Add(heightAttr); 389 | imgNode.Attributes.Add(widthAttr); 390 | } 391 | } 392 | #endregion 393 | } 394 | } 395 | -------------------------------------------------------------------------------- /OneNoteConversionTool/FormatReaders/PowerPointOpenXml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using DocumentFormat.OpenXml; 6 | using DocumentFormat.OpenXml.Office2010.PowerPoint; 7 | using DocumentFormat.OpenXml.Packaging; 8 | using DocumentFormat.OpenXml.Presentation; 9 | using Drawing = DocumentFormat.OpenXml.Drawing; 10 | using Shape = DocumentFormat.OpenXml.Presentation.Shape; 11 | 12 | 13 | namespace OneNoteConversionTool.FormatReaders 14 | { 15 | /// 16 | /// Obtains data from power point file using OpenXml 17 | /// 18 | public class PowerPointOpenXml 19 | { 20 | #region Global Variables 21 | private const string NewLine = "\n"; 22 | private readonly string _mPath; 23 | #endregion 24 | 25 | public PowerPointOpenXml(string filePath) 26 | { 27 | _mPath = filePath; 28 | } 29 | 30 | #region All Slides Info 31 | /// 32 | /// Gets the titles of all the slides 33 | /// 34 | /// 35 | public List GetAllSlideTitles() 36 | { 37 | var titles = new List(); 38 | 39 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 40 | { 41 | if (pDoc.PresentationPart != null) 42 | { 43 | foreach (var relsId in GetSlideRIds(pDoc)) 44 | { 45 | SlidePart slidePart = pDoc.PresentationPart.GetPartById(relsId) as SlidePart; 46 | titles.Add(GetSlideTitle(slidePart)); 47 | } 48 | } 49 | } 50 | 51 | return titles; 52 | } 53 | 54 | /// 55 | /// Gets the notes of all the slides 56 | /// 57 | /// 58 | public List GetAllSlideNotes() 59 | { 60 | var notes = new List(); 61 | 62 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 63 | { 64 | if (pDoc.PresentationPart != null) 65 | { 66 | List slideRIds = GetSlideRIds(pDoc); 67 | foreach (var relsId in slideRIds) 68 | { 69 | SlidePart slidePart = pDoc.PresentationPart.GetPartById(relsId) as SlidePart; 70 | notes.Add(GetSlideNotes(slidePart)); 71 | } 72 | } 73 | } 74 | 75 | return notes; 76 | } 77 | 78 | /// 79 | /// Gets the comments of all the slides 80 | /// 81 | /// 82 | public List GetAllSlideComments(bool includeAuthors = true) 83 | { 84 | var comments = new List(); 85 | 86 | var authors = new List(); 87 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 88 | { 89 | if (pDoc.PresentationPart != null 90 | && pDoc.PresentationPart.CommentAuthorsPart != null 91 | && pDoc.PresentationPart.CommentAuthorsPart.CommentAuthorList != null) 92 | { 93 | authors = pDoc.PresentationPart.CommentAuthorsPart.CommentAuthorList.Elements().ToList(); 94 | } 95 | 96 | if (pDoc.PresentationPart != null) 97 | { 98 | List slideRIds = GetSlideRIds(pDoc); 99 | foreach (var relsId in slideRIds) 100 | { 101 | SlidePart slidePart = pDoc.PresentationPart.GetPartById(relsId) as SlidePart; 102 | comments.Add(GetSlideComments(slidePart, authors, includeAuthors)); 103 | } 104 | } 105 | } 106 | 107 | return comments; 108 | } 109 | 110 | /// 111 | /// Get the number of slides 112 | /// 113 | /// True (default) if hidden slides should be included, false others 114 | /// 115 | public int NumberOfSlides(bool includeHidden = true) 116 | { 117 | int slideCount = 0; 118 | 119 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 120 | { 121 | if (pDoc.PresentationPart != null && pDoc.PresentationPart.SlideParts != null) 122 | { 123 | slideCount = includeHidden 124 | ? pDoc.PresentationPart.SlideParts.Count() 125 | : pDoc.PresentationPart.SlideParts.Count(s => !IsHiddenSlide(s)); 126 | } 127 | } 128 | 129 | return slideCount; 130 | } 131 | #endregion 132 | 133 | #region Single Slide Info 134 | /// 135 | /// Gets the title of the slide number 136 | /// 137 | /// slide number (one index) 138 | /// title of the slide 139 | public string GetSlideTitle(int slideNumber) 140 | { 141 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 142 | { 143 | SlidePart slidePart = GetSlidePart(pDoc, slideNumber); 144 | return GetSlideTitle(slidePart); 145 | } 146 | } 147 | 148 | /// 149 | /// Gets the notes of the slide 150 | /// 151 | /// slide number (one index) 152 | /// notes on the slide 153 | public string GetSlideNotes(int slideNumber) 154 | { 155 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 156 | { 157 | SlidePart slidePart = GetSlidePart(pDoc, slideNumber); 158 | return GetSlideNotes(slidePart); 159 | } 160 | } 161 | 162 | /// 163 | /// Gets the comments of the slide 164 | /// 165 | /// slide number (one index) 166 | /// comments on the slide 167 | public string GetSlideComments(int slideNumber, bool includeAuthor = true) 168 | { 169 | var authors = new List(); 170 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 171 | { 172 | if (pDoc.PresentationPart != null 173 | && pDoc.PresentationPart.CommentAuthorsPart != null 174 | && pDoc.PresentationPart.CommentAuthorsPart.CommentAuthorList != null) 175 | { 176 | authors = pDoc.PresentationPart.CommentAuthorsPart.CommentAuthorList.Elements().ToList(); 177 | } 178 | 179 | SlidePart slidePart = GetSlidePart(pDoc, slideNumber); 180 | return GetSlideComments(slidePart, authors, includeAuthor); 181 | } 182 | } 183 | 184 | /// 185 | /// Gets if the slide is hidden or not 186 | /// 187 | /// slide number (one index) 188 | /// True if the slide is hidden, false otherwise 189 | public bool IsHiddenSlide(int slideNumber) 190 | { 191 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 192 | { 193 | SlidePart slidePart = GetSlidePart(pDoc, slideNumber); 194 | return IsHiddenSlide(slidePart); 195 | } 196 | } 197 | #endregion 198 | 199 | #region Sections 200 | /// 201 | /// Get if the power point presentation has sections or not 202 | /// 203 | /// 204 | public bool HasSections() 205 | { 206 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 207 | { 208 | return GetListOfSections(pDoc).Count() != 0; 209 | } 210 | } 211 | 212 | /// 213 | /// Get names of all the sections 214 | /// 215 | /// 216 | public List GetSectionNames() 217 | { 218 | var sectionNames = new List(); 219 | 220 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 221 | { 222 | List
sections = GetListOfSections(pDoc); 223 | sectionNames.AddRange(sections.Select(section => GetSectionName(section))); 224 | } 225 | 226 | return sectionNames; 227 | } 228 | 229 | /// 230 | /// Get the slides that are in each section 231 | /// 232 | /// list of list of slides for each section 233 | /// each slide is represented as its slide number (one-indexed) 234 | public List> GetSlidesInSections() 235 | { 236 | var slidesInSections = new List>(); 237 | 238 | using (var pDoc = PresentationDocument.Open(_mPath, false)) 239 | { 240 | List
sections = GetListOfSections(pDoc); 241 | slidesInSections.AddRange(sections.Select(section => GetSlidesInSection(pDoc, section))); 242 | } 243 | 244 | return slidesInSections; 245 | } 246 | #endregion 247 | 248 | #region Private Methods 249 | #region Slide Info 250 | /// 251 | /// Get the title of the slide. 252 | /// Returns String.Empty if it can't find it 253 | /// 254 | /// 255 | /// 256 | private string GetSlideTitle(SlidePart slidePart) 257 | { 258 | if (slidePart == null || slidePart.Slide == null) 259 | { 260 | return String.Empty; 261 | } 262 | 263 | Shape shape = slidePart.Slide.Descendants().FirstOrDefault(IsTitleShape); 264 | if (shape == null || shape.TextBody == null) 265 | { 266 | return String.Empty; 267 | } 268 | 269 | return shape.TextBody.InnerText; 270 | } 271 | 272 | /// 273 | /// Get the notes of the slide. 274 | /// Returns String.Empty if it can't find it 275 | /// 276 | /// 277 | /// 278 | private string GetSlideNotes(SlidePart slidePart) 279 | { 280 | string notes = String.Empty; 281 | 282 | // check if this slide has any notes 283 | if (slidePart == null 284 | || slidePart.NotesSlidePart == null 285 | || slidePart.NotesSlidePart.NotesSlide == null) 286 | { 287 | return notes; 288 | } 289 | 290 | // Get all body shapes under notesSlide (that's where notes reside) 291 | List shapes = slidePart.NotesSlidePart.NotesSlide.Descendants().Where(IsBodyShape).ToList(); 292 | foreach (Shape shape in shapes) 293 | { 294 | // Get all paragraphes of the notes (each paragraph is a line in the notes) 295 | List paragraphs = shape.Descendants().ToList(); 296 | foreach (var paragraph in paragraphs) 297 | { 298 | // Get all runs (each run has different style) 299 | List runs = paragraph.Descendants().ToList(); 300 | foreach (var run in runs) 301 | { 302 | List styles = new List(); 303 | 304 | styles.Add("font-size:" + RunFontSize(run)); 305 | if (IsRunBold(run)) 306 | styles.Add("font-weight:bold"); 307 | if (IsRunItalic(run)) 308 | styles.Add("font-style:italic"); 309 | if (IsRunUnderlined(run) && IsRunStrikeThrough(run)) 310 | styles.Add("text-decoration:underline line-through"); 311 | else if (IsRunUnderlined(run)) 312 | styles.Add("text-decoration:underline"); 313 | else if (IsRunStrikeThrough(run)) 314 | styles.Add("text-decoration:line-through"); 315 | 316 | string style = String.Format("style=\"{0}\"", String.Join(";", styles.ToArray())); 317 | notes += String.Format("{1}", style, run.InnerText); 318 | } 319 | notes += NewLine; 320 | } 321 | } 322 | 323 | return Encoding.Default.GetString(Encoding.UTF8.GetBytes(notes)); 324 | } 325 | 326 | /// 327 | /// Get the comments of the slide. 328 | /// Returns String.Empty if it can't find it 329 | /// 330 | /// SlidePart of the slide 331 | /// List of comment authors 332 | /// 333 | /// 334 | private string GetSlideComments(SlidePart slidePart, List authors, bool includeAuthor = true) 335 | { 336 | string slideComments = String.Empty; 337 | 338 | // check if the slide has any comment list 339 | if (slidePart == null 340 | || slidePart.SlideCommentsPart == null 341 | || slidePart.SlideCommentsPart.CommentList == null) 342 | { 343 | return slideComments; 344 | } 345 | 346 | // Get all the comments in the given slide 347 | List comments = slidePart.SlideCommentsPart.CommentList.Elements().ToList(); 348 | foreach (var comment in comments) 349 | { 350 | // add the author name 351 | CommentAuthor author = authors.FirstOrDefault(a => a.Id.Value == comment.AuthorId.Value); 352 | if (author != null && author.Name != null && author.Name.HasValue && includeAuthor) 353 | { 354 | slideComments += "Author: " + author.Name.Value.ToString() + NewLine; 355 | } 356 | 357 | slideComments += comment.Text.InnerText + NewLine; 358 | } 359 | 360 | return Encoding.Default.GetString(Encoding.UTF8.GetBytes(slideComments)); 361 | } 362 | 363 | /// 364 | /// Gets the SlidePart based on the slide number 365 | /// 366 | /// 367 | /// 368 | /// 369 | private SlidePart GetSlidePart(PresentationDocument pDoc, int slideNumber) 370 | { 371 | int index = slideNumber - 1; 372 | if (pDoc.PresentationPart != null) 373 | { 374 | List slideRIds = GetSlideRIds(pDoc); 375 | if (0 <= index && index < slideRIds.Count) 376 | { 377 | return pDoc.PresentationPart.GetPartById(slideRIds[index]) as SlidePart; 378 | } 379 | } 380 | 381 | return null; 382 | } 383 | 384 | /// 385 | /// Get the relationship ids of the slides 386 | /// 387 | /// 388 | /// list of relationship ids for slides 389 | private List GetSlideRIds(PresentationDocument pDoc) 390 | { 391 | var ids = new List(); 392 | 393 | if (pDoc.PresentationPart == null 394 | || pDoc.PresentationPart.Presentation == null 395 | || pDoc.PresentationPart.Presentation.SlideIdList == null) 396 | { 397 | return ids; 398 | } 399 | 400 | ids.AddRange(from SlideId slideId in pDoc.PresentationPart.Presentation.SlideIdList select slideId.RelationshipId); 401 | 402 | return ids; 403 | } 404 | 405 | /// 406 | /// Get the ids of the slides 407 | /// 408 | /// 409 | /// list of ids for slides 410 | private List GetSlideIds(PresentationDocument pDoc) 411 | { 412 | var ids = new List(); 413 | 414 | if (pDoc.PresentationPart == null 415 | || pDoc.PresentationPart.Presentation == null 416 | || pDoc.PresentationPart.Presentation.SlideIdList == null) 417 | { 418 | return ids; 419 | } 420 | 421 | ids.AddRange(from SlideId slideId in pDoc.PresentationPart.Presentation.SlideIdList select slideId.Id); 422 | 423 | return ids; 424 | } 425 | 426 | /// 427 | /// Gets if the slide is hidden or not 428 | /// 429 | /// SlidePart of the slide 430 | /// True if the slide is hidden, false otherwise 431 | private bool IsHiddenSlide(SlidePart slidePart) 432 | { 433 | return ((slidePart.Slide == null) 434 | || (slidePart.Slide.Show != null && slidePart.Slide.Show.HasValue && !slidePart.Slide.Show.Value)); 435 | } 436 | 437 | /// 438 | /// Gets if the slide is hidden or not 439 | /// 440 | /// Slide of interest 441 | /// True if the slide is hidden, false otherwise 442 | private bool IsHiddenSlide(Slide slide) 443 | { 444 | return (slide == null) 445 | || (slide.Show != null && slide.Show.HasValue && !slide.Show.Value); 446 | } 447 | #endregion 448 | 449 | #region Section Info 450 | /// 451 | /// Get the name of the section 452 | /// 453 | /// 454 | /// 455 | private string GetSectionName(Section section) 456 | { 457 | 458 | return section.Name != null && section.Name.HasValue 459 | ? section.Name.Value.ToString() 460 | : String.Empty; 461 | } 462 | 463 | /// 464 | /// Get the slides in a given section 465 | /// 466 | /// the current presentation document 467 | /// the section of interest 468 | /// list of integers representating the slides in each section 469 | /// the slides are given by their slide number (one-indexed) 470 | private List GetSlidesInSection(PresentationDocument pDoc, Section section) 471 | { 472 | var slides = new List(); 473 | 474 | if (section.SectionSlideIdList == null) 475 | { 476 | return slides; 477 | } 478 | 479 | List slideIds = GetSlideIds(pDoc); 480 | foreach (SectionSlideIdListEntry slideId in section.SectionSlideIdList) 481 | { 482 | int index = slideIds.FindIndex(id => id.Value.Equals(slideId.Id.Value)); 483 | if (index != -1) 484 | { 485 | int slideNumber = index + 1; 486 | slides.Add(slideNumber); 487 | } 488 | } 489 | 490 | return slides; 491 | } 492 | 493 | /// 494 | /// Get list of all the sections 495 | /// 496 | /// 497 | /// 498 | private List
GetListOfSections(PresentationDocument pDoc) 499 | { 500 | var sections = new List
(); 501 | 502 | if (pDoc.PresentationPart == null) 503 | { 504 | return sections; 505 | } 506 | 507 | SectionList sectionList = pDoc.PresentationPart.Presentation.PresentationExtensionList.Descendants().FirstOrDefault(); 508 | if (sectionList == null) 509 | { 510 | return sections; 511 | } 512 | 513 | sections.AddRange(sectionList.Select(section => section as Section)); 514 | 515 | return sections; 516 | } 517 | #endregion 518 | 519 | /// 520 | /// Gets if this shape is for title or not 521 | /// 522 | /// Shape of interest 523 | /// True if it is title shape, false otherwise 524 | private bool IsTitleShape(Shape shape) 525 | { 526 | if (shape == null 527 | || shape.NonVisualShapeProperties == null 528 | || shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties == null) 529 | { 530 | return false; 531 | } 532 | 533 | PlaceholderShape phShape = shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.GetFirstChild(); 534 | 535 | return phShape != null 536 | && phShape.Type != null 537 | && phShape.Type.HasValue 538 | && (phShape.Type.Value == PlaceholderValues.Title || phShape.Type.Value == PlaceholderValues.CenteredTitle); 539 | } 540 | 541 | /// 542 | /// Gets if this shape is for body or not 543 | /// 544 | /// Shape of interest 545 | /// True if it is body shape, false otherwise 546 | private bool IsBodyShape(Shape shape) 547 | { 548 | if (shape == null 549 | || shape.NonVisualShapeProperties == null 550 | || shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties == null) 551 | { 552 | return false; 553 | } 554 | 555 | PlaceholderShape phShape = shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.GetFirstChild(); 556 | 557 | return phShape != null 558 | && phShape.Type != null 559 | && phShape.Type.HasValue 560 | && phShape.Type.Value == PlaceholderValues.Body; 561 | } 562 | 563 | /// 564 | /// Gets if this run is bold or not 565 | /// 566 | /// Run of interest 567 | /// True if it is bold, false otherwise 568 | private bool IsRunBold(Drawing.Run run) 569 | { 570 | var runProperty = run.Descendants().FirstOrDefault(); 571 | return runProperty.Bold != null && runProperty.Bold.Value; 572 | } 573 | 574 | /// 575 | /// Gets if this run is italic or not 576 | /// 577 | /// Run of interest 578 | /// True if it is italic, false otherwise 579 | private bool IsRunItalic(Drawing.Run run) 580 | { 581 | var runProperty = run.Descendants().FirstOrDefault(); 582 | return runProperty.Italic != null && runProperty.Italic.Value; 583 | } 584 | 585 | /// 586 | /// Gets if this run is underlined or not 587 | /// 588 | /// Run of interest 589 | /// True if it is underlined, false otherwise 590 | private bool IsRunUnderlined(Drawing.Run run) 591 | { 592 | var runProperty = run.Descendants().FirstOrDefault(); 593 | return runProperty.Underline != null 594 | && runProperty.Underline.Value != Drawing.TextUnderlineValues.None; 595 | } 596 | 597 | /// 598 | /// Gets if this run is Strike-through or not 599 | /// 600 | /// Run of interest 601 | /// True if it is strike-through, false otherwise 602 | private bool IsRunStrikeThrough(Drawing.Run run) 603 | { 604 | var runProperty = run.Descendants().FirstOrDefault(); 605 | return runProperty.Strike != null 606 | && runProperty.Strike.Value != Drawing.TextStrikeValues.NoStrike; 607 | } 608 | 609 | /// 610 | /// Gets the size of the text in the given run 611 | /// 612 | /// Run of interest 613 | /// Size of the font in points, 614 | /// default is 11.0pt 615 | private string RunFontSize(Drawing.Run run) 616 | { 617 | var runProperty = run.Descendants().FirstOrDefault(); 618 | if (runProperty.FontSize != null) 619 | return String.Format("{0:0.0}pt", runProperty.FontSize.Value / 100.0); 620 | else 621 | return "11.0pt"; 622 | } 623 | #endregion 624 | } 625 | } -------------------------------------------------------------------------------- /OneNoteConversionTool/OneNoteConversionForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace OneNoteConversionTool 2 | { 3 | partial class OneNoteConversionForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.browseFileButton = new System.Windows.Forms.Button(); 32 | this.openFileTextBox = new System.Windows.Forms.TextBox(); 33 | this.fileFormatComboBox = new System.Windows.Forms.ComboBox(); 34 | this.convertButton = new System.Windows.Forms.Button(); 35 | this.openFileLabel = new System.Windows.Forms.Label(); 36 | this.fileFormatLabel = new System.Windows.Forms.Label(); 37 | this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); 38 | this.outputLocationLabel = new System.Windows.Forms.Label(); 39 | this.outputLocationTextBox = new System.Windows.Forms.TextBox(); 40 | this.outputBrowseButton = new System.Windows.Forms.Button(); 41 | this.fileRadioButton = new System.Windows.Forms.RadioButton(); 42 | this.folderRadioButton = new System.Windows.Forms.RadioButton(); 43 | this.SuspendLayout(); 44 | // 45 | // browseFileButton 46 | // 47 | this.browseFileButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 48 | this.browseFileButton.Location = new System.Drawing.Point(421, 88); 49 | this.browseFileButton.Name = "browseFileButton"; 50 | this.browseFileButton.Size = new System.Drawing.Size(75, 23); 51 | this.browseFileButton.TabIndex = 3; 52 | this.browseFileButton.Text = "Browse ..."; 53 | this.browseFileButton.UseVisualStyleBackColor = true; 54 | this.browseFileButton.Click += new System.EventHandler(this.browseFileButton_Click); 55 | // 56 | // openFileTextBox 57 | // 58 | this.openFileTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 59 | | System.Windows.Forms.AnchorStyles.Right))); 60 | this.openFileTextBox.Location = new System.Drawing.Point(12, 62); 61 | this.openFileTextBox.Name = "openFileTextBox"; 62 | this.openFileTextBox.Size = new System.Drawing.Size(484, 20); 63 | this.openFileTextBox.TabIndex = 2; 64 | // 65 | // fileFormatComboBox 66 | // 67 | this.fileFormatComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 68 | | System.Windows.Forms.AnchorStyles.Right))); 69 | this.fileFormatComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 70 | this.fileFormatComboBox.FormattingEnabled = true; 71 | this.fileFormatComboBox.Location = new System.Drawing.Point(12, 128); 72 | this.fileFormatComboBox.Name = "fileFormatComboBox"; 73 | this.fileFormatComboBox.Size = new System.Drawing.Size(484, 21); 74 | this.fileFormatComboBox.TabIndex = 4; 75 | // 76 | // convertButton 77 | // 78 | this.convertButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 79 | | System.Windows.Forms.AnchorStyles.Right))); 80 | this.convertButton.Location = new System.Drawing.Point(12, 252); 81 | this.convertButton.Name = "convertButton"; 82 | this.convertButton.Size = new System.Drawing.Size(484, 58); 83 | this.convertButton.TabIndex = 7; 84 | this.convertButton.Text = "Convert to OneNote"; 85 | this.convertButton.UseVisualStyleBackColor = true; 86 | this.convertButton.Click += new System.EventHandler(this.convertButton_Click); 87 | // 88 | // openFileLabel 89 | // 90 | this.openFileLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 91 | | System.Windows.Forms.AnchorStyles.Right))); 92 | this.openFileLabel.AutoSize = true; 93 | this.openFileLabel.Location = new System.Drawing.Point(9, 23); 94 | this.openFileLabel.Name = "openFileLabel"; 95 | this.openFileLabel.Size = new System.Drawing.Size(106, 13); 96 | this.openFileLabel.TabIndex = 4; 97 | this.openFileLabel.Text = "Input path to convert"; 98 | // 99 | // fileFormatLabel 100 | // 101 | this.fileFormatLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 102 | | System.Windows.Forms.AnchorStyles.Right))); 103 | this.fileFormatLabel.AutoSize = true; 104 | this.fileFormatLabel.Location = new System.Drawing.Point(9, 112); 105 | this.fileFormatLabel.Name = "fileFormatLabel"; 106 | this.fileFormatLabel.Size = new System.Drawing.Size(79, 13); 107 | this.fileFormatLabel.TabIndex = 5; 108 | this.fileFormatLabel.Text = "Input file format"; 109 | // 110 | // outputLocationLabel 111 | // 112 | this.outputLocationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 113 | | System.Windows.Forms.AnchorStyles.Right))); 114 | this.outputLocationLabel.AutoSize = true; 115 | this.outputLocationLabel.Location = new System.Drawing.Point(10, 169); 116 | this.outputLocationLabel.Name = "outputLocationLabel"; 117 | this.outputLocationLabel.Size = new System.Drawing.Size(79, 13); 118 | this.outputLocationLabel.TabIndex = 8; 119 | this.outputLocationLabel.Text = "Output location"; 120 | // 121 | // outputLocationTextBox 122 | // 123 | this.outputLocationTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 124 | | System.Windows.Forms.AnchorStyles.Right))); 125 | this.outputLocationTextBox.Location = new System.Drawing.Point(12, 185); 126 | this.outputLocationTextBox.Name = "outputLocationTextBox"; 127 | this.outputLocationTextBox.Size = new System.Drawing.Size(484, 20); 128 | this.outputLocationTextBox.TabIndex = 5; 129 | // 130 | // outputBrowseButton 131 | // 132 | this.outputBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 133 | this.outputBrowseButton.Location = new System.Drawing.Point(421, 211); 134 | this.outputBrowseButton.Name = "outputBrowseButton"; 135 | this.outputBrowseButton.Size = new System.Drawing.Size(75, 23); 136 | this.outputBrowseButton.TabIndex = 6; 137 | this.outputBrowseButton.Text = "Browse ..."; 138 | this.outputBrowseButton.UseVisualStyleBackColor = true; 139 | this.outputBrowseButton.Click += new System.EventHandler(this.outputBrowseButton_Click); 140 | // 141 | // fileRadioButton 142 | // 143 | this.fileRadioButton.AutoSize = true; 144 | this.fileRadioButton.Checked = true; 145 | this.fileRadioButton.Location = new System.Drawing.Point(13, 39); 146 | this.fileRadioButton.Name = "fileRadioButton"; 147 | this.fileRadioButton.Size = new System.Drawing.Size(41, 17); 148 | this.fileRadioButton.TabIndex = 0; 149 | this.fileRadioButton.TabStop = true; 150 | this.fileRadioButton.Text = "File"; 151 | this.fileRadioButton.UseVisualStyleBackColor = true; 152 | // 153 | // folderRadioButton 154 | // 155 | this.folderRadioButton.AutoSize = true; 156 | this.folderRadioButton.Location = new System.Drawing.Point(61, 39); 157 | this.folderRadioButton.Name = "folderRadioButton"; 158 | this.folderRadioButton.Size = new System.Drawing.Size(54, 17); 159 | this.folderRadioButton.TabIndex = 1; 160 | this.folderRadioButton.Text = "Folder"; 161 | this.folderRadioButton.UseVisualStyleBackColor = true; 162 | // 163 | // OneNoteConversionForm 164 | // 165 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 166 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 167 | this.ClientSize = new System.Drawing.Size(509, 332); 168 | this.Controls.Add(this.folderRadioButton); 169 | this.Controls.Add(this.fileRadioButton); 170 | this.Controls.Add(this.outputLocationLabel); 171 | this.Controls.Add(this.outputLocationTextBox); 172 | this.Controls.Add(this.outputBrowseButton); 173 | this.Controls.Add(this.fileFormatLabel); 174 | this.Controls.Add(this.openFileLabel); 175 | this.Controls.Add(this.convertButton); 176 | this.Controls.Add(this.fileFormatComboBox); 177 | this.Controls.Add(this.openFileTextBox); 178 | this.Controls.Add(this.browseFileButton); 179 | this.Name = "OneNoteConversionForm"; 180 | this.Text = "OneNote Conversion Tool"; 181 | this.ResumeLayout(false); 182 | this.PerformLayout(); 183 | 184 | } 185 | 186 | #endregion 187 | 188 | private System.Windows.Forms.Button browseFileButton; 189 | private System.Windows.Forms.TextBox openFileTextBox; 190 | private System.Windows.Forms.ComboBox fileFormatComboBox; 191 | private System.Windows.Forms.Button convertButton; 192 | private System.Windows.Forms.Label openFileLabel; 193 | private System.Windows.Forms.Label fileFormatLabel; 194 | private System.Windows.Forms.OpenFileDialog openFileDialog; 195 | private System.Windows.Forms.Label outputLocationLabel; 196 | private System.Windows.Forms.TextBox outputLocationTextBox; 197 | private System.Windows.Forms.Button outputBrowseButton; 198 | private System.Windows.Forms.RadioButton folderRadioButton; 199 | private System.Windows.Forms.RadioButton fileRadioButton; 200 | } 201 | } 202 | 203 | -------------------------------------------------------------------------------- /OneNoteConversionTool/OneNoteConversionForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Windows.Forms; 4 | using Microsoft.WindowsAPICodePack.Dialogs; 5 | using OneNoteConversionTool.FormatConversion; 6 | 7 | namespace OneNoteConversionTool 8 | { 9 | public partial class OneNoteConversionForm : Form 10 | { 11 | private CommonOpenFileDialog _mInputFolderDialog; 12 | private CommonOpenFileDialog _mOutputPathDialog; 13 | 14 | public OneNoteConversionForm() 15 | { 16 | InitializeComponent(); 17 | InitializeDefaultSelections(); 18 | } 19 | 20 | private void InitializeDefaultSelections() 21 | { 22 | // Set filter options and filter index 23 | openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 24 | openFileDialog.Filter = GetFileDialogFilter(); 25 | openFileDialog.FilterIndex = 0; 26 | openFileDialog.Multiselect = true; 27 | 28 | // Set default input folder 29 | _mInputFolderDialog = new CommonOpenFileDialog(); 30 | _mInputFolderDialog.IsFolderPicker = true; 31 | _mInputFolderDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 32 | 33 | // Set default input format 34 | fileFormatComboBox.Items.AddRange(ConversionManager.GetSupportedFormats().ToArray()); 35 | fileFormatComboBox.SelectedIndex = 0; 36 | 37 | // Set default output folder 38 | _mOutputPathDialog = new CommonOpenFileDialog(); 39 | _mOutputPathDialog.IsFolderPicker = true; 40 | _mOutputPathDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 41 | outputLocationTextBox.Text = _mOutputPathDialog.InitialDirectory; 42 | 43 | // Event handlers 44 | fileRadioButton.Click += fileRadioButton_isClicked; 45 | folderRadioButton.Click += folderRadioButton_isClicked; 46 | } 47 | 48 | private void browseFileButton_Click(object sender, EventArgs e) 49 | { 50 | var startingDirectory = string.Empty; 51 | if (!string.IsNullOrEmpty(openFileTextBox.Text)) 52 | { 53 | startingDirectory = Path.GetDirectoryName(openFileTextBox.Text); 54 | } 55 | 56 | if (fileRadioButton.Checked) 57 | { 58 | if (!string.IsNullOrEmpty(startingDirectory) && Directory.Exists(startingDirectory)) 59 | { 60 | openFileDialog.InitialDirectory = startingDirectory; 61 | } 62 | else 63 | { 64 | openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 65 | openFileTextBox.Text = string.Empty; 66 | } 67 | 68 | DialogResult result = openFileDialog.ShowDialog(); 69 | 70 | if (result == DialogResult.OK) // Test result. 71 | { 72 | openFileTextBox.Text = openFileDialog.FileName; 73 | } 74 | } 75 | else if (folderRadioButton.Checked) 76 | { 77 | if (!string.IsNullOrEmpty(startingDirectory) && Directory.Exists(startingDirectory)) 78 | { 79 | _mInputFolderDialog.InitialDirectory = startingDirectory; 80 | } 81 | else 82 | { 83 | _mInputFolderDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 84 | openFileTextBox.Text = string.Empty; 85 | } 86 | 87 | var result = _mInputFolderDialog.ShowDialog(); 88 | 89 | if (result == CommonFileDialogResult.Ok) 90 | { 91 | openFileTextBox.Text = _mInputFolderDialog.FileName; 92 | } 93 | } 94 | } 95 | 96 | private void convertButton_Click(object sender, EventArgs e) 97 | { 98 | try 99 | { 100 | ConversionManager.ConvertInput(fileFormatComboBox.Text, openFileTextBox.Text, outputLocationTextBox.Text); 101 | MessageBox.Show("Finished conversion. Output File is located at:\n" + outputLocationTextBox.Text); 102 | } 103 | catch (Exception ex) 104 | { 105 | MessageBox.Show("Error during conversion:\n" + ex.Message); 106 | } 107 | } 108 | 109 | 110 | private void outputBrowseButton_Click(object sender, EventArgs e) 111 | { 112 | var result = _mOutputPathDialog.ShowDialog(); 113 | 114 | if (result == CommonFileDialogResult.Ok) 115 | { 116 | outputLocationTextBox.Text = _mOutputPathDialog.FileName; 117 | } 118 | } 119 | 120 | private void fileRadioButton_isClicked(object sender, EventArgs e) 121 | { 122 | fileRadioButton.Checked = true; 123 | folderRadioButton.Checked = false; 124 | } 125 | 126 | private void folderRadioButton_isClicked(object sender, EventArgs e) 127 | { 128 | fileRadioButton.Checked = false; 129 | folderRadioButton.Checked = true; 130 | } 131 | 132 | private string GetFileDialogFilter() 133 | { 134 | string[] fileDialogFilterStrings = 135 | { 136 | "All|*.*", 137 | "Word Files|*" + String.Join(";*", Utility.WordSupportedExtenssions), 138 | "PowerPoint Presentation|*" + String.Join(";*", Utility.PowerPointSupportedExtenssions), 139 | "PDF Files|*" + String.Join(";*", Utility.PdfSupportedExtenssions), 140 | "Epub|*" + String.Join(";*", Utility.EpubSupportedExtenssions), 141 | "InDesign|*" + String.Join(";*", Utility.InDesignSupportedExtenssions) 142 | }; 143 | return String.Join("|", fileDialogFilterStrings); 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /OneNoteConversionTool/OneNoteConversionForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /OneNoteConversionTool/OneNoteConversionTool.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DF6EFEF6-1D0D-4B64-A425-0A3758F5C251} 8 | WinExe 9 | Properties 10 | OneNoteConversionTool 11 | OneNoteConversionTool 12 | v4.5 13 | 512 14 | 32219f8b 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | TRACE;DEBUG 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | ..\packages\epubReader.1.0.0\lib\net40\eBdb.EpubReader.dll 39 | 40 | 41 | ..\packages\Ghostscript.NET.1.2.0\lib\net40\Ghostscript.NET.dll 42 | 43 | 44 | False 45 | ..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll 46 | 47 | 48 | ..\packages\epubReader.1.0.0\lib\net40\Ionic.Zip.dll 49 | 50 | 51 | 52 | False 53 | 54 | 55 | True 56 | 57 | 58 | True 59 | 60 | 61 | ..\packages\Microsoft.WindowsAPICodePack-Core.1.1.0.2\lib\Microsoft.WindowsAPICodePack.dll 62 | 63 | 64 | ..\packages\Microsoft.WindowsAPICodePack-Shell.1.1.0.0\lib\Microsoft.WindowsAPICodePack.Shell.dll 65 | 66 | 67 | ..\packages\Microsoft.WindowsAPICodePack-Shell.1.1.0.0\lib\Microsoft.WindowsAPICodePack.ShellExtensions.dll 68 | 69 | 70 | True 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Form 97 | 98 | 99 | OneNoteConversionForm.cs 100 | 101 | 102 | 103 | 104 | 105 | 106 | OneNoteConversionForm.cs 107 | 108 | 109 | ResXFileCodeGenerator 110 | Resources.Designer.cs 111 | Designer 112 | 113 | 114 | True 115 | Resources.resx 116 | 117 | 118 | Designer 119 | 120 | 121 | SettingsSingleFileGenerator 122 | Settings.Designer.cs 123 | 124 | 125 | True 126 | Settings.settings 127 | True 128 | 129 | 130 | 131 | 132 | Designer 133 | 134 | 135 | 136 | 137 | {451AF4B6-5D30-4D46-95CE-E4F900BF2D44} 138 | 1 139 | 0 140 | 0 141 | tlbimp 142 | False 143 | True 144 | 145 | 146 | {0002E157-0000-0000-C000-000000000046} 147 | 5 148 | 3 149 | 0 150 | primary 151 | False 152 | True 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 169 | -------------------------------------------------------------------------------- /OneNoteConversionTool/OutputGenerator/OneNoteGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Xml; 7 | using System.Xml.Linq; 8 | using Microsoft.Office.Interop.OneNote; 9 | 10 | namespace OneNoteConversionTool.OutputGenerator 11 | { 12 | /// 13 | /// Handles the interaction with the OneNote document output, including creating notebook, section, page, adding content, and other things 14 | /// 15 | public class OneNoteGenerator 16 | { 17 | #region Global Variables 18 | private const string NS = "http://schemas.microsoft.com/office/onenote/2013/onenote"; 19 | private const string WordOutline = @""; 20 | private const string HtmlOutline = @""; 21 | private const string XmlImageContent = "{0}"; 22 | 23 | private const string IsCollapsedAttrKey = "isCollapsed"; 24 | private const string PageLevelAttrKey = "pageLevel"; 25 | private const string ShowDateAttrKey = "showDate"; 26 | private const string ShowTimeAttrKey = "showTime"; 27 | 28 | private const int ContentBlockMargin = 20; 29 | private const int MaxPageWidth = 960; 30 | 31 | private readonly Application _mApp; 32 | private readonly string _mOutputPath; 33 | #endregion 34 | 35 | /// 36 | /// Constructor 37 | /// 38 | /// 39 | public OneNoteGenerator(string mOutputDir) 40 | { 41 | _mApp = new Application(); 42 | _mOutputPath = mOutputDir; 43 | } 44 | 45 | #region Scope Hierarchy 46 | /// 47 | /// Returns the children scope hierarchy of the OneNote object in XML format 48 | /// Gets the immediate child nodes of the start node, and no descendants in higher or lower subsection groups. 49 | /// 50 | /// 51 | /// 52 | public string GetChildrenScopeHierarchy(string objectId) 53 | { 54 | string xml; 55 | _mApp.GetHierarchy(objectId, HierarchyScope.hsChildren, out xml); 56 | return xml; 57 | } 58 | 59 | /// 60 | /// Returns the page scope hierarchy of the onenote object(page\section\notebook) in XML format 61 | /// Gets all pages below the start node, including all pages in section groups and subsection groups. 62 | /// 63 | /// 64 | /// 65 | public string GetPageScopeHierarchy(string objectId) 66 | { 67 | string xml; 68 | _mApp.GetHierarchy(objectId, HierarchyScope.hsPages, out xml); 69 | return xml; 70 | } 71 | 72 | /// 73 | /// Returns the section scope hierarchy of the onenote object(section\notebook) in XML format 74 | /// Gets all sections below the start node, including sections in section groups and subsection groups. 75 | /// 76 | /// 77 | /// 78 | public string GetSectionScopeHierarchy(string objectId) 79 | { 80 | string xml; 81 | _mApp.GetHierarchy(objectId, HierarchyScope.hsSections, out xml); 82 | return xml; 83 | } 84 | #endregion 85 | 86 | #region Creation 87 | /// 88 | /// Creates a new OneNote notebook with the given name 89 | /// 90 | /// 91 | /// 92 | public string CreateNotebook(string notebookName) 93 | { 94 | string notebookId; 95 | 96 | try 97 | { 98 | _mApp.OpenHierarchy(Path.Combine(_mOutputPath, notebookName), String.Empty, out notebookId, CreateFileType.cftNotebook); 99 | } 100 | catch (Exception e) 101 | { 102 | throw new ApplicationException("Error in CreateNotebook: " + e.Message, e); 103 | } 104 | 105 | return notebookId; 106 | } 107 | 108 | /// 109 | /// Creates one note section under the given notebook ID 110 | /// 111 | /// 112 | /// 113 | /// 114 | public string CreateSection(string sectionName, string notebookId) 115 | { 116 | string sectionId; 117 | 118 | try 119 | { 120 | //read notebook xml to get all the existed section names 121 | string docXml; 122 | _mApp.GetHierarchy(notebookId, HierarchyScope.hsSections, out docXml); 123 | var xDoc = XDocument.Parse(docXml); 124 | XNamespace xNs = xDoc.Root.Name.Namespace; 125 | var sectionNames = xDoc.Root.Elements(xNs + "Section").Select(section => section.Attribute("name").Value); 126 | 127 | //if sectionName already exist, set sectionName as sectionName (2), and etc.. 128 | int ordinal = 2; 129 | var adjustedSectionName = sectionName; 130 | while (sectionNames.Contains(adjustedSectionName)) 131 | { 132 | adjustedSectionName = sectionName + " (" + ordinal + ")"; 133 | ++ordinal; 134 | } 135 | 136 | _mApp.OpenHierarchy(adjustedSectionName + ".one", notebookId, out sectionId, CreateFileType.cftSection); 137 | } 138 | catch (Exception e) 139 | { 140 | throw new ApplicationException("Error in CreateSection: " + e.Message, e); 141 | } 142 | return sectionId; 143 | } 144 | 145 | /// 146 | /// Creates a one note page under the given section ID 147 | /// 148 | /// 149 | /// 150 | /// 151 | public string CreatePage(string pageName, string sectionId) 152 | { 153 | string pageId; 154 | try 155 | { 156 | _mApp.CreateNewPage(sectionId, out pageId, NewPageStyle.npsBlankPageWithTitle); 157 | 158 | // Get the title and set it to our page name 159 | string xml; 160 | _mApp.GetPageContent(pageId, out xml, PageInfo.piAll); 161 | var doc = XDocument.Parse(xml); 162 | var ns = doc.Root.Name.Namespace; 163 | var title = doc.Descendants(ns + "T").First(); 164 | title.Value = pageName; 165 | 166 | // Update the page 167 | _mApp.UpdatePageContent(doc.ToString()); 168 | 169 | } 170 | catch (Exception e) 171 | { 172 | throw new ApplicationException("Error in CreatePage: " + e.Message, e); 173 | } 174 | return pageId; 175 | } 176 | 177 | /// 178 | /// Generates a Table of Content Page of all the pages underneath the given section 179 | /// Also sets the Table of Content Page to be the first page in the given section 180 | /// 181 | /// 182 | /// 183 | /// 184 | public string CreateTableOfContentPage(string sectionId, string tocPageTitle = "Table of Contents") 185 | { 186 | string retVal = CreatePage(tocPageTitle, sectionId); 187 | 188 | var sectionHierarchy = GetChildrenScopeHierarchy(sectionId); 189 | 190 | XDocument xdoc = XDocument.Parse(sectionHierarchy); 191 | XNamespace xNs = xdoc.Root.Name.Namespace; 192 | var sectionElement = xdoc.Elements(xNs + "Section") 193 | .Single(x => x.Attribute("ID").Value.Equals(sectionId)); 194 | 195 | var tocContent = string.Empty; 196 | 197 | var pageElements = sectionElement.Elements(xNs + "Page"); 198 | 199 | //Iterate through the sections and get hyperlinks for them to be put into the new page. 200 | foreach (var pageElement in pageElements) 201 | { 202 | var pageId = pageElement.Attribute("ID").Value; 203 | 204 | //Don't add a link to the ToC page itself 205 | if (pageId != retVal) 206 | { 207 | var pageTitle = pageElement.Attribute("name").Value; 208 | pageTitle = Encoding.Default.GetString(Encoding.UTF8.GetBytes(pageTitle)); 209 | string hyperLink; 210 | 211 | _mApp.GetHyperlinkToObject(pageId, string.Empty, out hyperLink); 212 | 213 | var pageLevel = int.Parse(pageElement.Attribute("pageLevel").Value); 214 | 215 | while (pageLevel > 1) 216 | { 217 | tocContent += "\t"; 218 | --pageLevel; 219 | } 220 | 221 | tocContent += string.Format("{1}", hyperLink, pageTitle) + "\n\n"; 222 | } 223 | } 224 | 225 | AddPageContent(retVal, tocContent); 226 | 227 | //Move the ToC page to the first page 228 | SetAsFirstPage(retVal, sectionId); 229 | 230 | return retVal; 231 | } 232 | #endregion 233 | 234 | #region Modify Page 235 | /// 236 | /// Sets the page attribute to the given value 237 | /// 238 | /// ID of the page 239 | /// The attribute of interest 240 | /// The new value of the attribute 241 | public void SetPageAttribute(string pageId, string attr, string value) 242 | { 243 | try 244 | { 245 | // get the page 246 | XmlDocument doc = GetPageContent(pageId); 247 | XmlNode page = doc.DocumentElement; 248 | if (page == null || page.Attributes == null) return; 249 | if (page.Attributes[attr] == null) 250 | { 251 | XmlAttribute xAttr = doc.CreateAttribute(attr); 252 | xAttr.Value = value; 253 | page.Attributes.Append(xAttr); 254 | } 255 | else 256 | { 257 | page.Attributes[attr].Value = value; 258 | } 259 | 260 | // update the page 261 | _mApp.UpdatePageContent(doc.OuterXml); 262 | } 263 | catch (Exception e) 264 | { 265 | throw new ApplicationException("Error in SetPageAttribute: " + e.Message, e); 266 | } 267 | } 268 | 269 | /// 270 | /// Sets the page title attribute to the given value 271 | /// 272 | /// ID of the page 273 | /// The attribute of interest for one:Title node 274 | /// The new value of the attribute 275 | public void SetPageTitleAttribute(string pageId, string attr, string value) 276 | { 277 | try 278 | { 279 | // get the page 280 | XmlDocument doc = GetPageContent(pageId); 281 | XmlNode page = doc.DocumentElement; 282 | if (page == null) return; 283 | XmlNode title = page.SelectSingleNode("//one:Title", GetNSManager(doc.NameTable)); 284 | if (title == null || title.Attributes == null) return; 285 | 286 | if (title.Attributes[attr] == null) 287 | { 288 | XmlAttribute xAttr = doc.CreateAttribute(attr); 289 | xAttr.Value = value; 290 | title.Attributes.Append(xAttr); 291 | } 292 | else 293 | { 294 | title.Attributes[attr].Value = value; 295 | } 296 | 297 | // update the page 298 | _mApp.UpdatePageContent(doc.OuterXml); 299 | } 300 | catch (Exception e) 301 | { 302 | throw new ApplicationException("Error in SetPageTitleAttribute", e); 303 | } 304 | } 305 | 306 | /// 307 | /// Make the page as subpage (if isSet true) or promote it (if isSet if false) 308 | /// 309 | /// 310 | /// 311 | /// defaults to true, if true, increment pageLevel, else decrement pageLevel 312 | public void SetSubPage(string sectionId, string pageId, bool isSet = true) 313 | { 314 | try 315 | { 316 | string hierarchy = string.Empty; 317 | _mApp.GetHierarchy(sectionId, HierarchyScope.hsPages, out hierarchy); 318 | 319 | XmlDocument doc = new XmlDocument(); 320 | doc.LoadXml(hierarchy); 321 | 322 | string xpath = string.Format("//one:Page[@ID='{0}']", pageId); 323 | 324 | XmlNode page = doc.SelectSingleNode(xpath, GetNSManager(doc.NameTable)); 325 | var pageLevel = int.Parse(page.Attributes["pageLevel"].Value); 326 | 327 | 328 | if (isSet) 329 | { 330 | ++pageLevel; 331 | } 332 | else 333 | { 334 | --pageLevel; 335 | pageLevel = pageLevel > 0 ? pageLevel : 1; 336 | } 337 | 338 | page.Attributes["pageLevel"].Value = pageLevel.ToString(); 339 | _mApp.UpdateHierarchy(doc.OuterXml); 340 | } 341 | catch (Exception e) 342 | { 343 | throw new ApplicationException("Error in SetAsSubPage: " + e.Message, e); 344 | } 345 | } 346 | 347 | /// 348 | /// Sets the page level of a given page (note, page level must be {1, 2, or 3}) 349 | /// 350 | /// 351 | /// 352 | public void SetPageLevel(string pageId, int pageLevel) 353 | { 354 | // ensure that page level is within acceptable range = [1, 3] 355 | pageLevel = pageLevel < 1 ? 1 : pageLevel; 356 | pageLevel = pageLevel > 3 ? 3 : pageLevel; 357 | 358 | SetPageAttribute(pageId, PageLevelAttrKey, pageLevel.ToString()); 359 | } 360 | 361 | /// 362 | /// Sets the collapse attribute of the page to hide or unhide the subpages under the given page 363 | /// 364 | /// ID of the page 365 | /// isCollapsed attribute value 366 | public void SetCollapsePage(string pageId, bool isCollapsed = true) 367 | { 368 | SetPageAttribute(pageId, IsCollapsedAttrKey, isCollapsed.ToString().ToLower()); 369 | } 370 | 371 | /// 372 | /// Sets whether the date should be shown or not in the page 373 | /// 374 | /// 375 | /// 376 | public void SetShowDate(string pageId, bool isShown = true) 377 | { 378 | SetPageTitleAttribute(pageId, ShowDateAttrKey, isShown.ToString().ToLower()); 379 | } 380 | 381 | /// 382 | /// Sets whether the time should be shown or not in the page 383 | /// 384 | /// 385 | /// 386 | public void SetShowTime(string pageId, bool isShown = true) 387 | { 388 | SetPageTitleAttribute(pageId, ShowTimeAttrKey, isShown.ToString().ToLower()); 389 | } 390 | 391 | /// 392 | /// Adds the content to the corresponding page. 393 | /// 394 | /// Page Identifier in which the content to be displayed. 395 | /// The content which needs to be added to the page. 396 | /// Starting vertical position of the block in the page in Pixels from the top of the page 397 | /// Maximum width of the outline block where the content is added 398 | public void AddPageContent(string pageId, string content, int yPos = 80, int width = 520) 399 | { 400 | var doc = GetPageContent(pageId); 401 | var page = doc.SelectSingleNode("//one:Page", GetNSManager(doc.NameTable)); 402 | if (page == null) 403 | return; 404 | 405 | var childOutline = doc.CreateElement("one:Outline", NS); 406 | 407 | try 408 | { 409 | childOutline.InnerText = string.Format(WordOutline, yPos, content, width); 410 | 411 | 412 | page.AppendChild(childOutline); 413 | string childContent = Utility.UnescapeXml(childOutline.InnerXml); 414 | string newPageContent = doc.InnerXml.Replace(childOutline.InnerXml, childContent); 415 | _mApp.UpdatePageContent(newPageContent, DateTime.MinValue); 416 | } 417 | catch (Exception e) 418 | { 419 | throw new ApplicationException("Error in AddPageContent: " + e.Message, e); 420 | } 421 | } 422 | 423 | /// 424 | /// Adds the content as a HTML block. 425 | /// 426 | /// Id of the page 427 | /// content to be added 428 | /// Starting position of the block 429 | /// Width of the block 430 | public void AddPageContentAsHtmlBlock(string pageId, string content, int yPos = 80, int width = 520) 431 | { 432 | var doc = GetPageContent(pageId); 433 | var page = doc.SelectSingleNode("//one:Page", GetNSManager(doc.NameTable)); 434 | if (page == null) 435 | return; 436 | 437 | try 438 | { 439 | //If outline doesn't exist, create one 440 | if (doc.SelectSingleNode("//one:Page/one:Outline", GetNSManager(doc.NameTable)) == null) 441 | { 442 | XmlNode childOutline = doc.CreateElement("one:Outline", NS); 443 | 444 | childOutline.InnerText = string.Format(HtmlOutline, yPos, width, content); 445 | 446 | page.AppendChild(childOutline); 447 | string childContent = Utility.UnescapeXml(childOutline.InnerXml); 448 | string newPageContent = doc.InnerXml.Replace(childOutline.InnerXml, childContent); 449 | 450 | //Override the content 451 | _mApp.UpdatePageContent(newPageContent, DateTime.MinValue); 452 | } 453 | else 454 | { 455 | UpdatePageContent(pageId, content); 456 | } 457 | } 458 | catch (Exception e) 459 | { 460 | throw new ApplicationException("Error in AddPageContent: " + e.Message, e); 461 | } 462 | } 463 | 464 | /// 465 | /// Adds an image to the page 466 | /// The width of the page is at most MaxPageWidth (960 pixels) 467 | /// If the width is bigger, the image is proportionally minimized to MaxPageWidth 468 | /// 469 | /// 470 | /// 471 | /// 472 | public void AddImageToPage(string pageId, Image img, int yPos = 80) 473 | { 474 | if (img == null) 475 | return; 476 | 477 | Size size = new Size(img.Width, img.Height); 478 | if (img.Width > MaxPageWidth) 479 | { 480 | size.Height = (size.Height*MaxPageWidth)/(size.Width); 481 | size.Width = MaxPageWidth; 482 | } 483 | 484 | // convert the image 485 | Bitmap bitmap = new Bitmap(img, size); 486 | MemoryStream stream = new MemoryStream(); 487 | bitmap.Save(stream, img.RawFormat); 488 | string imgString = Convert.ToBase64String(stream.ToArray()); 489 | 490 | // get the image xml 491 | string imgXmlStr = String.Format(XmlImageContent, imgString, bitmap.Width, bitmap.Height, yPos); 492 | 493 | // get the page 494 | XmlDocument doc = GetPageContent(pageId); 495 | XmlNode page = doc.DocumentElement; 496 | if (page == null) return; 497 | XmlNode imgNode = doc.CreateNode(XmlNodeType.Element, "one:Image", NS); 498 | page.AppendChild(imgNode); 499 | imgNode.InnerXml = imgXmlStr; 500 | 501 | // update the page adding the image 502 | _mApp.UpdatePageContent(doc.OuterXml); 503 | } 504 | 505 | /// 506 | /// Adds the content at the end of the corresponding page. 507 | /// 508 | /// Id of the page 509 | /// content to be added 510 | /// Width of the block 511 | public void AppendPageContent(string pageId, string content, int width = 520) 512 | { 513 | AddPageContent(pageId, content, (int) GetPageHeight(pageId) + ContentBlockMargin, width); 514 | } 515 | 516 | /// 517 | /// Adds the content as HTML block at the end of the corresponding page 518 | /// 519 | /// ID of the page 520 | /// HTML block to be added 521 | /// Width of the block 522 | public void AppendPageContentAsHtmlBlock(string pageId, string content, int width = 520) 523 | { 524 | AddPageContentAsHtmlBlock(pageId, content, (int) GetPageHeight(pageId) + ContentBlockMargin, width); 525 | } 526 | 527 | /// 528 | /// Adds the image at the end of the corresponding page 529 | /// 530 | /// ID of the page 531 | /// The Image to be added 532 | public void AppendImageToPage(string pageId, Image img) 533 | { 534 | AddImageToPage(pageId, img, (int)GetPageHeight(pageId) + ContentBlockMargin); 535 | } 536 | 537 | /// 538 | /// UpdatePageContent 539 | /// this method is invoked when a previous page word section 540 | /// needs to be updated 541 | /// 542 | /// 543 | /// 544 | public void UpdatePageContent(string pageId, string content) 545 | { 546 | var doc = GetPageContent(pageId); 547 | var children = doc.SelectSingleNode("//one:Page/one:Outline[position() = last()]/one:OEChildren", GetNSManager(doc.NameTable)); 548 | var htmBlock = doc.CreateElement("one:HTMLBlock", NS); 549 | 550 | try 551 | { 552 | htmBlock.InnerText = string.Format(@"", content); 553 | children.AppendChild(htmBlock); 554 | 555 | string newPageContent = doc.InnerXml.Replace(htmBlock.InnerXml, Utility.UnescapeXml(htmBlock.InnerXml)); 556 | _mApp.UpdatePageContent(newPageContent, DateTime.MinValue); 557 | } 558 | catch (Exception e) 559 | { 560 | throw new ApplicationException("Error in UpdatePageContent: " + e.Message, e); 561 | } 562 | } 563 | 564 | /// 565 | /// set a page as the first page in the section 566 | /// 567 | /// 568 | /// 569 | public void SetAsFirstPage(string pageId, string sectionId) 570 | { 571 | var sectionXml = GetChildrenScopeHierarchy(sectionId); 572 | var xDoc = XDocument.Parse(sectionXml); 573 | XNamespace xNs = xDoc.Root.Name.Namespace; 574 | var sectionElement = xDoc.Elements(xNs + "Section") 575 | .Single(x => x.Attribute("ID").Value.Equals(sectionId)); 576 | 577 | var pageElements = sectionElement.Elements(xNs + "Page"); 578 | if (pageElements.Count() > 1) 579 | { 580 | var page = pageElements.Single(x => x.Attribute("ID").Value.Equals(pageId)); 581 | page.Remove(); 582 | 583 | sectionElement.Elements(xNs + "Page").FirstOrDefault().AddBeforeSelf(page); 584 | _mApp.UpdateHierarchy(xDoc.ToString()); 585 | } 586 | } 587 | 588 | /// 589 | /// Removes the author from any node in the page 590 | /// 591 | /// 592 | public void RemoveAuthor(string pageId) 593 | { 594 | var doc = GetPageContent(pageId); 595 | var nodes = doc.SelectNodes("//*[@author or @authorInitials or @lastModifiedBy or @lastModifiedByInitials]", GetNSManager(doc.NameTable)); 596 | 597 | if (nodes == null) 598 | return; 599 | 600 | foreach (XmlNode node in nodes) 601 | { 602 | if (node.Attributes == null) 603 | continue; 604 | 605 | if (node.Attributes["author"] != null) 606 | node.Attributes["author"].Value = String.Empty; 607 | if (node.Attributes["authorInitials"] != null) 608 | node.Attributes["authorInitials"].Value = String.Empty; 609 | if (node.Attributes["lastModifiedBy"] != null) 610 | node.Attributes["lastModifiedBy"].Value = String.Empty; 611 | if (node.Attributes["lastModifiedByInitials"] != null) 612 | node.Attributes["lastModifiedByInitials"].Value = String.Empty; 613 | } 614 | 615 | // update the page 616 | _mApp.UpdatePageContent(doc.OuterXml); 617 | } 618 | #endregion 619 | 620 | #region Get 621 | /// 622 | /// Gets the ID of an existing notebook in the current directory 623 | /// 624 | /// name of the notebook of interest 625 | /// ID of the notebook of interest 626 | public string GetNotebook(string notebookName) 627 | { 628 | string notebookId; 629 | 630 | try 631 | { 632 | _mApp.OpenHierarchy(Path.Combine(_mOutputPath, notebookName), String.Empty, out notebookId); 633 | } 634 | catch (Exception e) 635 | { 636 | throw new ApplicationException("Error in GetNotebook: " + e.Message, e); 637 | } 638 | 639 | return notebookId; 640 | } 641 | 642 | /// 643 | /// Gets the ID of an existing section in the given notebook 644 | /// If more than one exists, it returns the first one 645 | /// 646 | /// section name 647 | /// ID of the notebook where the section exists 648 | /// 649 | public string GetSection(string sectionName, string notebookId) 650 | { 651 | string sectionId; 652 | 653 | try 654 | { 655 | _mApp.OpenHierarchy(sectionName + ".one", notebookId, out sectionId); 656 | } 657 | catch (Exception e) 658 | { 659 | throw new ApplicationException("Error in GetSection: " + e.Message, e); 660 | } 661 | 662 | return sectionId; 663 | } 664 | 665 | /// 666 | /// Gets the ID o fan existing page in the given section 667 | /// If more than one exists, it returns the first one 668 | /// 669 | /// page name 670 | /// ID of the section where the page exists 671 | /// 672 | public string GetPage(string pageName, string sectionId) 673 | { 674 | var pageId = String.Empty; 675 | 676 | try 677 | { 678 | XmlDocument xDoc = new XmlDocument(); 679 | xDoc.LoadXml(GetPageScopeHierarchy(sectionId)); 680 | XmlNode node = xDoc.SelectSingleNode(String.Format("//one:Page[@name='{0}']", pageName), GetNSManager(xDoc.NameTable)); 681 | if (node != null && node.Attributes != null) 682 | pageId = node.Attributes["ID"].Value; 683 | } 684 | catch (Exception e) 685 | { 686 | throw new ApplicationException("Error in GetPage: " + e.Message, e); 687 | } 688 | 689 | return pageId; 690 | } 691 | 692 | /// 693 | /// GetPageContent 694 | /// return DOM representation of onenote's page 695 | /// 696 | /// 697 | /// 698 | public XmlDocument GetPageContent(string pageId) 699 | { 700 | var doc = new XmlDocument(); 701 | try 702 | { 703 | string pageInfo; 704 | _mApp.GetPageContent(pageId, out pageInfo, PageInfo.piAll); 705 | doc.LoadXml(pageInfo); 706 | } 707 | catch (Exception e) 708 | { 709 | throw new ApplicationException("Error in GetPageContent: " + e.Message + pageId.ToString(), e); 710 | } 711 | return doc; 712 | } 713 | 714 | /// 715 | /// get the hyper link to the object 716 | /// 717 | /// 718 | /// 719 | public string GetHyperLinkToObject(string objectId) 720 | { 721 | string hyperLink; 722 | _mApp.GetHyperlinkToObject(objectId, String.Empty, out hyperLink); 723 | return hyperLink; 724 | } 725 | 726 | /// 727 | /// Get the height of the page 728 | /// 729 | /// id of the page 730 | /// height of the page (default is 80.0 if there are no elements in the page) 731 | public double GetPageHeight(string pageId) 732 | { 733 | double retVal = 80.0; 734 | 735 | XmlDocument xmlPageDoc = GetPageContent(pageId); 736 | XmlNodeList nodeList = xmlPageDoc.SelectNodes("//*[one:Position]", GetNSManager(xmlPageDoc.NameTable)); 737 | if (nodeList != null) 738 | { 739 | foreach (XmlNode node in nodeList) 740 | { 741 | XmlElement xmlPosition = node["one:Position"]; 742 | XmlElement xmlSize = node["one:Size"]; 743 | if (xmlPosition == null || xmlSize == null) continue; 744 | 745 | XmlAttribute xmlY = xmlPosition.Attributes["y"]; 746 | XmlAttribute xmlHeight = xmlSize.Attributes["height"]; 747 | 748 | double y = xmlY == null ? 0 : Double.Parse(xmlY.Value); 749 | double height = xmlHeight == null ? 0 : Double.Parse(xmlHeight.Value); 750 | 751 | retVal = Math.Max(retVal, y + height); 752 | } 753 | } 754 | 755 | return retVal; 756 | } 757 | 758 | /// 759 | /// Get the height of the page 760 | /// 761 | /// id of the page 762 | /// height of the page (default is 520.0 if there are no elements in the page) 763 | public double GetPageWidth(string pageId) 764 | { 765 | double retVal = 520.0; 766 | 767 | XmlDocument xmlPageDoc = GetPageContent(pageId); 768 | XmlNodeList nodeList = xmlPageDoc.SelectNodes("//*[one:Position]", GetNSManager(xmlPageDoc.NameTable)); 769 | if (nodeList != null) 770 | { 771 | foreach (XmlNode node in nodeList) 772 | { 773 | XmlElement xmlPosition = node["one:Position"]; 774 | XmlElement xmlSize = node["one:Size"]; 775 | if (xmlPosition == null || xmlSize == null) continue; 776 | 777 | XmlAttribute xmlWidth = xmlSize.Attributes["width"]; 778 | 779 | double width = xmlWidth == null ? 0 : Double.Parse(xmlWidth.Value); 780 | 781 | retVal = Math.Max(retVal, width); 782 | } 783 | } 784 | 785 | return retVal; 786 | } 787 | 788 | /// 789 | /// Gets the value of an attribute of the page 790 | /// 791 | /// ID of the page 792 | /// the attribute of interest 793 | /// the value of the attribute 794 | public string GetPageAttribute(string pageId, string attr) 795 | { 796 | try 797 | { 798 | string hierarchy; 799 | string sectionId; 800 | _mApp.GetHierarchyParent(pageId, out sectionId); 801 | _mApp.GetHierarchy(sectionId, HierarchyScope.hsPages, out hierarchy); 802 | 803 | var doc = new XmlDocument(); 804 | doc.LoadXml(hierarchy); 805 | 806 | string xpath = String.Format("//one:Page[@ID='{0}']", pageId); 807 | XmlNode page = doc.SelectSingleNode(xpath, GetNSManager(doc.NameTable)); 808 | 809 | if (page == null || page.Attributes == null || page.Attributes[attr] == null) return String.Empty; 810 | 811 | return page.Attributes[attr].Value; 812 | } 813 | catch (Exception e) 814 | { 815 | throw new ApplicationException("Error in GetPageAttribute: " + e.Message, e); 816 | } 817 | } 818 | #endregion 819 | 820 | #region Private Methods 821 | /// 822 | /// Returns the namespace manager from the passed xml name table. 823 | /// 824 | /// Name table of the xml document. 825 | /// Returns the namespace manager. 826 | private XmlNamespaceManager GetNSManager(XmlNameTable nameTable) 827 | { 828 | var nsManager = new XmlNamespaceManager(nameTable); 829 | try 830 | { 831 | nsManager.AddNamespace("one", NS); 832 | } 833 | catch (Exception e) 834 | { 835 | throw new ApplicationException("Error in GetNSManager: " + e.Message, e); 836 | } 837 | return nsManager; 838 | } 839 | #endregion 840 | } 841 | } 842 | -------------------------------------------------------------------------------- /OneNoteConversionTool/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace OneNoteConversionTool 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new OneNoteConversionForm()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /OneNoteConversionTool/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("OneNoteConversionTool")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("OneNoteConversionTool")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("98a9e18a-0e24-4532-9d76-c88f4af07156")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /OneNoteConversionTool/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34014 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OneNoteConversionTool.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OneNoteConversionTool.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap redX { 67 | get { 68 | object obj = ResourceManager.GetObject("redX", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /OneNoteConversionTool/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\redX.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | -------------------------------------------------------------------------------- /OneNoteConversionTool/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34014 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OneNoteConversionTool.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /OneNoteConversionTool/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OneNoteConversionTool/Resources/redX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OneNoteDev/OneNoteConversionTool/7022a7808ccc30204c384664fa2e01ce31d5a46c/OneNoteConversionTool/Resources/redX.jpg -------------------------------------------------------------------------------- /OneNoteConversionTool/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | using System.Web; 5 | 6 | namespace OneNoteConversionTool 7 | { 8 | /// 9 | /// Class that contains a bunch of helper methods for ConversionTool 10 | /// 11 | public class Utility 12 | { 13 | #region Available Extenssions 14 | public static string[] WordSupportedExtenssions = { ".doc", ".docx", ".dot", ".dotx", ".docm", ".dotm", ".odt" }; 15 | public static string[] PowerPointSupportedExtenssions = { ".ppt", ".pptx", ".pot", ".potx", ".pptm", ".potm", ".odp" }; 16 | public static string[] PdfSupportedExtenssions = { ".pdf" }; 17 | public static string[] EpubSupportedExtenssions = { ".epub" }; 18 | public static string[] InDesignSupportedExtenssions = { ".indd" }; 19 | #endregion 20 | 21 | #region Files and Folders Utility Methods 22 | /// 23 | /// Helper method to create a directory 24 | /// 25 | /// 26 | /// 27 | public static string CreateDirectory(string pathDir) 28 | { 29 | string retPath = pathDir; 30 | int i = 1; 31 | // ensure that the name of the directory is unique 32 | while (Directory.Exists(retPath)) 33 | { 34 | retPath = String.Format("{0} ({1})", retPath, i); 35 | i++; 36 | } 37 | // create the directory 38 | Directory.CreateDirectory(retPath); 39 | 40 | return retPath; 41 | } 42 | 43 | /// 44 | /// Helper method to get a path of a new folder in a given directory 45 | /// Note: this method doesn't create the folder 46 | /// 47 | /// Directory where the folder will be created 48 | /// Name of the folder 49 | /// Full path of the new folder 50 | public static string NewFolderPath(string dir, string folderName) 51 | { 52 | if (dir == null || folderName == null) 53 | { 54 | Console.WriteLine("Error in NewFolderPath: One of the parameters is null"); 55 | return String.Empty; 56 | } 57 | if (!Directory.Exists(dir)) 58 | { 59 | Console.WriteLine("Error in NewFolderPath: {0} doesn't exist", dir); 60 | return String.Empty; 61 | } 62 | 63 | // make the folder name "New Folder" if it was empty 64 | folderName = folderName != String.Empty ? folderName : "New Folder"; 65 | 66 | string retPath = Path.Combine(dir, folderName); 67 | int i = 1; 68 | while (Directory.Exists(retPath)) 69 | { 70 | retPath = String.Format("{0} {1}", Path.Combine(dir, folderName), i); 71 | i++; 72 | } 73 | return retPath; 74 | } 75 | 76 | /// 77 | /// Helper method to get a path of a new file in a given directory 78 | /// Note: this method doesn't create the file 79 | /// 80 | /// Directory where the file will be created 81 | /// Name of the file 82 | /// Extension of the file 83 | /// full path of the new file 84 | public static string NewFilePath(string dir, string fileName, string extension) 85 | { 86 | if (dir == null || fileName == null || extension == null) 87 | { 88 | Console.WriteLine("Error in NewFilePath: One of the parameters is null"); 89 | return String.Empty; 90 | } 91 | if (!Directory.Exists(dir)) 92 | { 93 | Console.WriteLine("Error in NewFilePath: {0} doesn't exist", dir); 94 | return String.Empty; 95 | } 96 | 97 | // make the file name "New File" if it was empty 98 | fileName = fileName != String.Empty ? fileName : "New File"; 99 | 100 | string fullFileName = Path.Combine(dir, fileName); 101 | string retPath = Path.ChangeExtension(fullFileName, extension); 102 | int i = 1; 103 | while (File.Exists(retPath)) 104 | { 105 | retPath = String.Format("{0} {1}{2}", fullFileName, i, extension); 106 | i++; 107 | } 108 | 109 | return retPath; 110 | } 111 | 112 | /// 113 | /// Helper method to delete directory and its contents recursively 114 | /// 115 | /// 116 | /// 117 | public static bool DeleteDirectory(string targetDir) 118 | { 119 | bool retVal = false; 120 | 121 | try 122 | { 123 | Directory.Delete(targetDir, true); 124 | retVal = true; 125 | } 126 | catch 127 | { 128 | Console.WriteLine("Failed to delete directory: {0}", targetDir); 129 | } 130 | 131 | return retVal; 132 | } 133 | #endregion 134 | 135 | #region Html/Xml Utility Methods 136 | /// 137 | /// Changes the escape sequence characters with the equivalant characters. 138 | /// 139 | /// Document content. 140 | /// The converted string is being returned. 141 | public static string UnescapeXml(string docContent) 142 | { 143 | string unxml = docContent; 144 | try 145 | { 146 | if (!string.IsNullOrEmpty(unxml)) 147 | { 148 | // replace entities with literal values 149 | StringWriter sw = new StringWriter(); 150 | HttpUtility.HtmlDecode(unxml, sw); 151 | unxml = sw.ToString(); 152 | unxml = Encoding.UTF8.GetString(Encoding.Default.GetBytes(unxml)); 153 | } 154 | } 155 | catch (Exception e) 156 | { 157 | throw new ApplicationException("Error in UnescapeXml", e); 158 | } 159 | return unxml; 160 | } 161 | #endregion 162 | } 163 | } -------------------------------------------------------------------------------- /OneNoteConversionTool/bin/Debug/OneNoteConversionTool.vshost.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /OneNoteConversionTool/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/FormatConversion/ConversionManagerUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace OneNoteConversionToolUnitTest.FormatConversion 7 | { 8 | /// 9 | /// UnitTest class for ConversionManager 10 | /// 11 | [TestClass] 12 | public class ConversionManagerUnitTest 13 | { 14 | private static string _mTestPath = string.Empty; 15 | private const string TestDoc = "test.doc"; 16 | private const string TestDocx = "test.docx"; 17 | private const string TestPdf = "test.pdf"; 18 | private const string TestPpt = "test.ppt"; 19 | private const string TestPptx = "test.pptx"; 20 | private const string TestIndd = "test.indd"; 21 | private const string TestUnsupported = "test.blah"; 22 | 23 | /// 24 | /// Gets or sets the test context which provides 25 | /// information about and functionality for the current test run. 26 | /// 27 | public TestContext TestContext { get; set; } 28 | 29 | /// 30 | /// Use ClassInitialize to run code before running the first test in the class 31 | /// 32 | /// 33 | [ClassInitialize()] 34 | public static void Initialize(TestContext testContext) 35 | { 36 | _mTestPath = Path.GetTempPath() + "ConversionTest\\"; 37 | 38 | if (!Directory.Exists(_mTestPath)) 39 | { 40 | Directory.CreateDirectory(_mTestPath); 41 | } 42 | 43 | File.Create(_mTestPath + TestDoc); 44 | File.Create(_mTestPath + TestDocx); 45 | File.Create(_mTestPath + TestPdf); 46 | File.Create(_mTestPath + TestPpt); 47 | File.Create(_mTestPath + TestPptx); 48 | File.Create(_mTestPath + TestIndd); 49 | File.Create(_mTestPath + TestUnsupported); 50 | } 51 | 52 | /// 53 | /// Gets invoked after all unit tests have been run for this class 54 | /// 55 | [ClassCleanup()] 56 | public static void CleanUp() 57 | { 58 | if (Directory.Exists(_mTestPath)) 59 | { 60 | Utility.DeleteDirectory(_mTestPath); 61 | } 62 | } 63 | 64 | /// 65 | /// Gets called for each test method 66 | /// 67 | [TestInitialize()] 68 | public void TestInitialize() 69 | { 70 | MockConversionManager.InitializeWithMockData(); 71 | } 72 | 73 | /// 74 | /// Verifies that the list supported formats are returned correctly 75 | /// 76 | [TestMethod] 77 | public void ValidateSupportedFormats() 78 | { 79 | var expectedFormats = new List(); 80 | expectedFormats.Add(MockFormatConverter.InputFormat); 81 | 82 | var supportedFormats = MockConversionManager.GetSupportedFormats(); 83 | 84 | CollectionAssert.AreEqual(expectedFormats, supportedFormats); 85 | } 86 | 87 | /// 88 | /// Verifies that the ConvertWordToOneNote method is called for *.doc input format 89 | /// 90 | [TestMethod] 91 | public void ValidateConvertInputDoc() 92 | { 93 | MockConversionManager.ConvertInput(MockFormatConverter.InputFormat, _mTestPath + TestDoc, _mTestPath); 94 | Assert.IsTrue(MockConversionManager.GetMockFormatConverter().IsWordToOneNoteCalled); 95 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPdfToOneNoteCalled); 96 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPowerPointToOneNoteCalled); 97 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsInDesignToOneNoteCalled); 98 | } 99 | 100 | /// 101 | /// Verifies that the ConvertWordToOneNote method is called for *.docx input format 102 | /// 103 | [TestMethod] 104 | public void ValidateConvertInputDocx() 105 | { 106 | 107 | MockConversionManager.ConvertInput(MockFormatConverter.InputFormat, _mTestPath + TestDocx, _mTestPath); 108 | Assert.IsTrue(MockConversionManager.GetMockFormatConverter().IsWordToOneNoteCalled); 109 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPdfToOneNoteCalled); 110 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPowerPointToOneNoteCalled); 111 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsInDesignToOneNoteCalled); 112 | } 113 | 114 | /// 115 | /// Verifies that the ConvertPDFToOneNote method is called for *.pdf input format 116 | /// 117 | [TestMethod] 118 | public void ValidateConvertInputPdf() 119 | { 120 | MockConversionManager.ConvertInput(MockFormatConverter.InputFormat, _mTestPath + TestPdf, _mTestPath); 121 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsWordToOneNoteCalled); 122 | Assert.IsTrue(MockConversionManager.GetMockFormatConverter().IsPdfToOneNoteCalled); 123 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPowerPointToOneNoteCalled); 124 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsInDesignToOneNoteCalled); 125 | } 126 | 127 | /// 128 | /// Verifies that the ConvertPowerPointToOneNote method is called for *.ppt input format 129 | /// 130 | [TestMethod] 131 | public void ValidateConvertInputPpt() 132 | { 133 | MockConversionManager.ConvertInput(MockFormatConverter.InputFormat, _mTestPath + TestPpt, _mTestPath); 134 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsWordToOneNoteCalled); 135 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPdfToOneNoteCalled); 136 | Assert.IsTrue(MockConversionManager.GetMockFormatConverter().IsPowerPointToOneNoteCalled); 137 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsInDesignToOneNoteCalled); 138 | } 139 | 140 | /// 141 | /// Verifies that the ConvertPowerPointToOneNote method is called for *.pptx input format 142 | /// 143 | [TestMethod] 144 | public void ValidateConvertInputPptx() 145 | { 146 | MockConversionManager.ConvertInput(MockFormatConverter.InputFormat, _mTestPath + TestPptx, _mTestPath); 147 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsWordToOneNoteCalled); 148 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPdfToOneNoteCalled); 149 | Assert.IsTrue(MockConversionManager.GetMockFormatConverter().IsPowerPointToOneNoteCalled); 150 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsInDesignToOneNoteCalled); 151 | } 152 | 153 | /// 154 | /// Verifies that the ConvertInDesignToOneNote method is called for *.indd input format 155 | /// 156 | [TestMethod] 157 | public void ValidateConvertInputIndd() 158 | { 159 | MockConversionManager.ConvertInput(MockFormatConverter.InputFormat, _mTestPath + TestIndd, _mTestPath); 160 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsWordToOneNoteCalled); 161 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPdfToOneNoteCalled); 162 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPowerPointToOneNoteCalled); 163 | Assert.IsTrue(MockConversionManager.GetMockFormatConverter().IsInDesignToOneNoteCalled); 164 | } 165 | 166 | /// 167 | /// Verifies that an exception is thrown for a file format that is not expected 168 | /// 169 | [TestMethod] 170 | public void ValidateConvertInputNotSupportedFile() 171 | { 172 | MockConversionManager.ConvertInput(MockFormatConverter.InputFormat, _mTestPath + TestUnsupported, _mTestPath); 173 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsWordToOneNoteCalled); 174 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPdfToOneNoteCalled); 175 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsPowerPointToOneNoteCalled); 176 | Assert.IsFalse(MockConversionManager.GetMockFormatConverter().IsInDesignToOneNoteCalled); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/FormatConversion/GenericFormatConverterUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Xml.Linq; 7 | using Microsoft.Office.Interop.Word; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | using OneNoteConversionTool.FormatConversion; 10 | using OneNoteConversionTool.OutputGenerator; 11 | using _WordApplication = Microsoft.Office.Interop.Word._Application; 12 | using _WordDocument = Microsoft.Office.Interop.Word._Document; 13 | 14 | namespace OneNoteConversionToolUnitTest.FormatConversion 15 | { 16 | /// 17 | /// Unit test for GenericFormatConverter 18 | /// 19 | [TestClass] 20 | public class GenericFormatConverterUnitTest 21 | { 22 | //Page titles of the generated word document 23 | private static readonly List DocPageTitles = new List() { "Table of Contents", "this is the first page", "this is the second page", "this is the third page" }; 24 | private static readonly List PptPageTitles = new List() { "Table of Contents", "MainSection", "PresentationTitle", "FirstSection", "Some New Section", "Third Slide", "SecondSection", "PageTitle" }; 25 | private static readonly List EpubPageTitles = new List() { "Epub Sample Cover", "Epub Sample TOC", "Epub Sample Page" }; 26 | 27 | private const string TestDocName = "GenericTest.docx"; 28 | private const string TestPptName = "..\\..\\Resources\\SectionSample.pptx"; 29 | private const string TestEpubFile = "..\\..\\Resources\\EpubSample.epub"; 30 | private const string NotebookName = "Generic"; 31 | private static readonly string TestDocPath = Path.Combine(Utility.TempFolder, TestDocName); 32 | private static readonly string TestPptPath = Path.Combine(Environment.CurrentDirectory, TestPptName); 33 | private static readonly string TestEpubPath = Path.Combine(Environment.CurrentDirectory, TestEpubFile); 34 | private static string _mNotebookId = String.Empty; 35 | private static XNamespace _mXmlNs; 36 | private static OneNoteGenerator _mOnGenerator; 37 | 38 | /// 39 | /// Create temporary folders and initialize OneNote Generator 40 | /// 41 | [ClassInitialize()] 42 | public static void MyClassInitialize(TestContext testContext) 43 | { 44 | if (!Directory.Exists(Utility.RootFolder)) 45 | { 46 | Directory.CreateDirectory(Utility.RootFolder); 47 | } 48 | if (!Directory.Exists(Utility.TempFolder)) 49 | { 50 | Directory.CreateDirectory(Utility.TempFolder); 51 | } 52 | _mXmlNs = Utility.NS; 53 | _mOnGenerator = new OneNoteGenerator(Utility.RootFolder); 54 | //Get Id of the test notebook so we chould retrieve generated content 55 | //KindercareFormatConverter will create notebookName as Kindercare 56 | _mNotebookId = _mOnGenerator.CreateNotebook(NotebookName); 57 | 58 | var word = new Application(); 59 | var doc = word.Application.Documents.Add(); 60 | 61 | //add pages to doc 62 | for (int i = 1; i < DocPageTitles.Count; i++) 63 | { 64 | doc.Content.Text += DocPageTitles[i]; 65 | doc.Words.Last.InsertBreak(WdBreakType.wdPageBreak); 66 | } 67 | 68 | var filePath = TestDocPath as object; 69 | doc.SaveAs(ref filePath); 70 | ((_WordDocument)doc).Close(); 71 | ((_WordApplication)word).Quit(); 72 | } 73 | 74 | /// 75 | /// Delete temporary folders 76 | /// 77 | [ClassCleanup()] 78 | public static void MyClassCleanup() 79 | { 80 | //delete temporary folders 81 | if (Directory.Exists(Utility.RootFolder)) 82 | { 83 | Utility.DeleteDirectory(Utility.RootFolder); 84 | } 85 | if (Directory.Exists(Utility.NonExistentOutputPath)) 86 | { 87 | Utility.DeleteDirectory(Utility.NonExistentOutputPath); 88 | } 89 | } 90 | 91 | /// 92 | /// create a simple docx file 93 | /// and validate its conversion 94 | /// 95 | [TestMethod] 96 | public void ValidateWordConversion() 97 | { 98 | var converter = new GenericFormatConverter(); 99 | converter.ConvertWordToOneNote(TestDocPath, Utility.RootFolder); 100 | 101 | //retrieve xml from generated notebook 102 | var xmlDoc = _mOnGenerator.GetPageScopeHierarchy(_mNotebookId); 103 | Assert.IsNotNull(xmlDoc); 104 | 105 | // retrieve the section for the ppt conversion 106 | string sectionName = Path.GetFileNameWithoutExtension(TestDocPath); 107 | XDocument xDoc = XDocument.Parse(xmlDoc); 108 | XElement xSection = xDoc.Descendants(_mXmlNs + "Section").FirstOrDefault(x => x.Attribute("name").Value.Equals(sectionName)); 109 | Assert.IsNotNull(xSection); 110 | 111 | //get the xml of each pages 112 | var extractedPageTitles = xSection.Descendants(_mXmlNs + "Page").Select(x => x.Attribute("name").Value).ToList(); 113 | CollectionAssert.AreEqual(DocPageTitles, extractedPageTitles); 114 | } 115 | 116 | /// 117 | /// validate the conversion of the ppt file in the resources folder (SectionSample.pptx) 118 | /// 119 | [TestMethod] 120 | public void ValidatePowerPointConversion() 121 | { 122 | var converter = new GenericFormatConverter(); 123 | converter.ConvertPowerPointToOneNote(TestPptPath, Utility.RootFolder); 124 | 125 | // retrieve xml from generated notebook 126 | var xmlDoc = _mOnGenerator.GetPageScopeHierarchy(_mNotebookId); 127 | Assert.IsNotNull(xmlDoc); 128 | 129 | // retrieve the section for the ppt conversion 130 | string sectionName = Path.GetFileNameWithoutExtension(TestPptPath); 131 | XDocument xDoc = XDocument.Parse(xmlDoc); 132 | XElement xSection = xDoc.Descendants(_mXmlNs + "Section").FirstOrDefault(x => x.Attribute("name").Value.Equals(sectionName)); 133 | Assert.IsNotNull(xSection); 134 | 135 | //get the xml of each pages 136 | var extractedPageTitles = xSection.Descendants(_mXmlNs + "Page").Select(x => x.Attribute("name").Value).ToList(); 137 | CollectionAssert.AreEqual(PptPageTitles, extractedPageTitles); 138 | } 139 | 140 | /// 141 | /// Validate the conversion of the epub file in the resources folder (EpubSample.epub) 142 | /// 143 | [TestMethod] 144 | public void ValidateEpubConversion() 145 | { 146 | var converter = new GenericFormatConverter(); 147 | converter.ConvertEpubToOneNote(TestEpubPath, Utility.RootFolder); 148 | 149 | // retrieve xml from generated notebook 150 | var xmlDoc = _mOnGenerator.GetPageScopeHierarchy(_mNotebookId); 151 | Assert.IsNotNull(xmlDoc); 152 | 153 | // retrieve the section for the ppt conversion 154 | string sectionName = Path.GetFileNameWithoutExtension(TestEpubPath); 155 | XDocument xDoc = XDocument.Parse(xmlDoc); 156 | XElement xSection = xDoc.Descendants(_mXmlNs + "Section").FirstOrDefault(x => x.Attribute("name").Value.Equals(sectionName)); 157 | Assert.IsNotNull(xSection); 158 | 159 | //get the xml of each pages 160 | var extractedPageTitles = xSection.Descendants(_mXmlNs + "Page").Select(x => x.Attribute("name").Value).ToList(); 161 | CollectionAssert.AreEqual(EpubPageTitles, extractedPageTitles); 162 | } 163 | 164 | /// 165 | /// When the input file doesn't exist, 166 | /// word failed to open it and throw a COMException 167 | /// 168 | [TestMethod] 169 | [ExpectedException(typeof(COMException))] 170 | public void ValidateNonExistFileConversion() 171 | { 172 | var inputFile = Utility.NonExistentInputFile; 173 | var converter = new GenericFormatConverter(); 174 | converter.ConvertWordToOneNote(inputFile, Utility.RootFolder); 175 | } 176 | 177 | /// 178 | /// When the output folder doesn't exist, 179 | /// it should work without throwing any exceptions 180 | /// 181 | [TestMethod] 182 | public void ValidateNonExistOutputFolder() 183 | { 184 | var outputDir = Utility.NonExistentOutputPath; 185 | var converter = new GenericFormatConverter(); 186 | converter.ConvertWordToOneNote(TestDocPath, outputDir); 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/FormatConversion/KindercareFormatConverterUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Xml.Linq; 7 | using Microsoft.Office.Interop.Word; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | using OneNoteConversionTool.FormatConversion; 10 | using OneNoteConversionTool.OutputGenerator; 11 | using _WordApplication = Microsoft.Office.Interop.Word._Application; 12 | using _WordDocument = Microsoft.Office.Interop.Word._Document; 13 | 14 | namespace OneNoteConversionToolUnitTest.FormatConversion 15 | { 16 | /// 17 | /// Unit Test for KindercareFormatConverter 18 | /// 19 | [TestClass] 20 | public class KindercareFormatConverterUnitTest 21 | { 22 | //Page titles of the generated word document 23 | private static List pageTitles = new List() { "Table of Contents", "Users Content Table", "First", "Second", "Last" }; 24 | 25 | private const string NotebookName = "Kindercare"; 26 | private const string TestDocName = "KindercareTest.docx"; 27 | private static readonly string TestDocPath = Path.Combine(Utility.TempFolder, TestDocName); 28 | private static string _mNotebookId = String.Empty; 29 | private static XNamespace _mXmlNs; 30 | private static OneNoteGenerator _mOnGenerator; 31 | 32 | /// 33 | /// Create temporary folders and initialize OneNote Generator 34 | /// 35 | [ClassInitialize()] 36 | public static void MyClassInitialize(TestContext testContext) 37 | { 38 | if (!Directory.Exists(Utility.RootFolder)) 39 | { 40 | Directory.CreateDirectory(Utility.RootFolder); 41 | } 42 | if (!Directory.Exists(Utility.TempFolder)) 43 | { 44 | Directory.CreateDirectory(Utility.TempFolder); 45 | } 46 | _mXmlNs = Utility.NS; 47 | _mOnGenerator = new OneNoteGenerator(Utility.RootFolder); 48 | 49 | //Get Id of the test notebook so we chould retrieve generated content 50 | //KindercareFormatConverter will create notebookName as Kindercare 51 | _mNotebookId = _mOnGenerator.CreateNotebook(NotebookName); 52 | 53 | // used to generate a test docx 54 | var word = new Application(); 55 | var doc = word.Application.Documents.Add(); 56 | 57 | //construct "table of content" page 58 | //skip the first one, which will be generated by converter 59 | foreach(var s in pageTitles.Skip(1)) 60 | { 61 | doc.Content.Text += s; 62 | } 63 | 64 | //construct other pages 65 | for (int i = 2; i < pageTitles.Count; i++) 66 | { 67 | doc.Words.Last.InsertBreak(WdBreakType.wdPageBreak); 68 | doc.Content.Text += pageTitles[i]; 69 | doc.Content.Text += "this is a sample page"; 70 | } 71 | 72 | //save the docx as a temporary file 73 | var fileFullPath = TestDocPath as object; 74 | doc.SaveAs(ref fileFullPath); 75 | ((_WordDocument)doc).Close(); 76 | ((_WordApplication)word).Quit(); 77 | } 78 | 79 | /// 80 | /// Delete temporary folders 81 | /// 82 | [ClassCleanup()] 83 | public static void MyClassCleanup() 84 | { 85 | //delete temporary folders 86 | if (Directory.Exists(Utility.RootFolder)) 87 | { 88 | Utility.DeleteDirectory(Utility.RootFolder); 89 | } 90 | if (Directory.Exists(Utility.NonExistentOutputPath)) 91 | { 92 | Utility.DeleteDirectory(Utility.NonExistentOutputPath); 93 | } 94 | } 95 | 96 | /// 97 | /// Validate the conversion of a simple word document 98 | /// 99 | [TestMethod] 100 | public void ValidateWordConversion() 101 | { 102 | //convert the docx 103 | var converter = new KindercareFormatConverter(); 104 | converter.ConvertWordToOneNote(TestDocPath, Utility.RootFolder); 105 | 106 | //retrieve the xml of generated notebook (OneNote.HierarchyScope.hsPages) 107 | var xmlDoc = _mOnGenerator.GetPageScopeHierarchy(_mNotebookId); 108 | Assert.IsNotNull(xmlDoc); 109 | 110 | XDocument xdoc = XDocument.Parse(xmlDoc); 111 | //get all the page xml 112 | var extractedPageTitles = xdoc.Descendants(_mXmlNs + "Page").Select(page => page.Attribute("name").Value).ToList(); 113 | 114 | CollectionAssert.AreEqual(pageTitles, extractedPageTitles); 115 | } 116 | 117 | /// 118 | /// When the input file doesn't exist, 119 | /// word failed to open it and throw a COMException 120 | /// 121 | [TestMethod] 122 | [ExpectedException(typeof(COMException))] 123 | public void ValidateNonExistFileConversion() 124 | { 125 | var inputFile = Utility.NonExistentInputFile; 126 | var converter = new KindercareFormatConverter(); 127 | converter.ConvertWordToOneNote(inputFile, Utility.RootFolder); 128 | } 129 | 130 | /// 131 | /// When the output folder don't exist 132 | /// it should work without throwing any exceptions 133 | /// 134 | [TestMethod] 135 | public void ValidateNonExistOutputFolder() 136 | { 137 | var outputDir = Utility.NonExistentOutputPath; 138 | var converter = new KindercareFormatConverter(); 139 | converter.ConvertWordToOneNote(TestDocPath, outputDir); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/FormatConversion/MockConversionManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using OneNoteConversionTool.FormatConversion; 3 | 4 | namespace OneNoteConversionToolUnitTest.FormatConversion 5 | { 6 | /// 7 | /// Mock conversion class for unit testing 8 | /// 9 | class MockConversionManager : ConversionManager 10 | { 11 | /// 12 | /// Replaces the registered converters with mock ones 13 | /// 14 | public static void InitializeWithMockData() 15 | { 16 | var converter = new MockFormatConverter(); 17 | SupportedConverters = new Dictionary(); 18 | SupportedConverters.Add(converter.GetSupportedInputFormat(), converter); 19 | } 20 | 21 | /// 22 | /// Returns the instance of the MockFormatConverter 23 | /// 24 | /// 25 | public static MockFormatConverter GetMockFormatConverter() 26 | { 27 | return SupportedConverters[MockFormatConverter.InputFormat] as MockFormatConverter; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/FormatConversion/MockFormatConverter.cs: -------------------------------------------------------------------------------- 1 | using OneNoteConversionTool.FormatConversion; 2 | 3 | namespace OneNoteConversionToolUnitTest.FormatConversion 4 | { 5 | /// 6 | /// A mock FormatConverter that implements IFormatConverter for unit testing purposes 7 | /// 8 | class MockFormatConverter : IFormatConverter 9 | { 10 | public const string InputFormat = "MockFormat"; 11 | 12 | public bool IsWordToOneNoteCalled = false; 13 | public bool IsPdfToOneNoteCalled = false; 14 | public bool IsPowerPointToOneNoteCalled = false; 15 | public bool IsInDesignToOneNoteCalled = false; 16 | public bool IsEpubToOneNoteCalled = false; 17 | 18 | public bool ConvertWordToOneNote(string inputFile, string outputDir) 19 | { 20 | IsWordToOneNoteCalled = true; 21 | return IsWordToOneNoteCalled; 22 | } 23 | 24 | public bool ConvertPdfToOneNote(string inputFile, string outputDir) 25 | { 26 | IsPdfToOneNoteCalled = true; 27 | return IsPdfToOneNoteCalled; 28 | } 29 | 30 | public bool ConvertPowerPointToOneNote(string inputFile, string outputDir) 31 | { 32 | IsPowerPointToOneNoteCalled = true; 33 | return IsPowerPointToOneNoteCalled; 34 | } 35 | 36 | public bool ConvertInDesignToOneNote(string inputFile, string outputDir) 37 | { 38 | IsInDesignToOneNoteCalled = true; 39 | return IsInDesignToOneNoteCalled; 40 | } 41 | 42 | public bool ConvertEpubToOneNote(string inputFile, string outputDir) 43 | { 44 | IsEpubToOneNoteCalled = true; 45 | return IsEpubToOneNoteCalled; 46 | } 47 | 48 | public string GetSupportedInputFormat() 49 | { 50 | return InputFormat; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/FormatConversion/SmsgrFormatConverterUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Xml.Linq; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | using OneNoteConversionTool.FormatConversion; 9 | using OneNoteConversionTool.OutputGenerator; 10 | 11 | namespace OneNoteConversionToolUnitTest.FormatConversion 12 | { 13 | [TestClass] 14 | public class SmsgrFormatConverterUnitTest 15 | { 16 | private static readonly List PptPageTitles = new List() { "Table of Contents", "MainSection", "PresentationTitle", "FirstSection", "Some New Section", "Third Slide", "SecondSection", "PageTitle" }; 17 | 18 | private const string TestPptName = "..\\..\\Resources\\SectionSample.pptx"; 19 | private static readonly string TestPptPath = Path.Combine(Environment.CurrentDirectory, TestPptName); 20 | private const string TrainerNotebookName = "Trainer Notebook"; 21 | private const string StudentNotebookName = "Student Notebook"; 22 | 23 | private static XNamespace _mXmlNs; 24 | private static OneNoteGenerator _mOnGenerator; 25 | private static string _mTrainerNotebookId = String.Empty; 26 | private static string _mStudentNotebookId = String.Empty; 27 | 28 | /// 29 | /// Create temporary folders and initialize onenote generator 30 | /// 31 | /// 32 | [ClassInitialize()] 33 | public static void MyClassInitialize(TestContext testContext) 34 | { 35 | if (!Directory.Exists(Utility.RootFolder)) 36 | { 37 | Directory.CreateDirectory(Utility.RootFolder); 38 | } 39 | if (!Directory.Exists(Utility.TempFolder)) 40 | { 41 | Directory.CreateDirectory(Utility.TempFolder); 42 | } 43 | _mXmlNs = Utility.NS; 44 | _mOnGenerator = new OneNoteGenerator(Utility.RootFolder); 45 | // Get the id of the Trainer and student notebooks 46 | _mTrainerNotebookId = _mOnGenerator.CreateNotebook(TrainerNotebookName); 47 | _mStudentNotebookId = _mOnGenerator.CreateNotebook(StudentNotebookName); 48 | } 49 | 50 | /// 51 | /// Delete temporary folders at cleanup 52 | /// 53 | [ClassCleanup()] 54 | public static void MyClassCleanup() 55 | { 56 | //delete temporary folders 57 | if (Directory.Exists(Utility.RootFolder)) 58 | { 59 | Utility.DeleteDirectory(Utility.RootFolder); 60 | } 61 | if (Directory.Exists(Utility.NonExistentOutputPath)) 62 | { 63 | Utility.DeleteDirectory(Utility.NonExistentOutputPath); 64 | } 65 | } 66 | 67 | /// 68 | /// Validate the conversion of the ppt file in the resources folder (SectionSample.pptx) 69 | /// 70 | [TestMethod] 71 | public void ValidatePowerPointConversion() 72 | { 73 | var converter = new SmsgrFormatConverter(); 74 | converter.ConvertPowerPointToOneNote(TestPptPath, Utility.RootFolder); 75 | 76 | ValidateTrainerNotebook(); 77 | ValidateStudentNotebook(); 78 | } 79 | 80 | /// 81 | /// When the input file doesn't exist, 82 | /// word failed to open it and throw a COMException 83 | /// 84 | [TestMethod] 85 | [ExpectedException(typeof(COMException))] 86 | public void ValidateNonExistFileConversion() 87 | { 88 | var inputFile = Utility.NonExistentInputFile; 89 | var converter = new SmsgrFormatConverter(); 90 | converter.ConvertWordToOneNote(inputFile, Utility.RootFolder); 91 | } 92 | 93 | /// 94 | /// When the output folder doesn't exist, 95 | /// it should work without throwing any exceptions 96 | /// 97 | [TestMethod] 98 | public void ValidateNonExistOutputFolder() 99 | { 100 | var outputDir = Utility.NonExistentOutputPath; 101 | var converter = new SmsgrFormatConverter(); 102 | converter.ConvertPowerPointToOneNote(TestPptPath, outputDir); 103 | } 104 | 105 | /// 106 | /// Validate the Trainer notebook 107 | /// 108 | private static void ValidateTrainerNotebook() 109 | { 110 | // retrieve xml from generated notebook 111 | var xmlDoc = _mOnGenerator.GetPageScopeHierarchy(_mTrainerNotebookId); 112 | Assert.IsNotNull(xmlDoc); 113 | 114 | // retrieve the section for the ppt conversion 115 | string sectionName = Path.GetFileNameWithoutExtension(TestPptPath); 116 | XDocument xDoc = XDocument.Parse(xmlDoc); 117 | XElement xSection = xDoc.Descendants(_mXmlNs + "Section").FirstOrDefault(x => x.Attribute("name").Value.Equals(sectionName)); 118 | Assert.IsNotNull(xSection); 119 | 120 | //get the xml of each pages 121 | var extractedPageTitles = xSection.Descendants(_mXmlNs + "Page").Select(x => x.Attribute("name").Value).ToList(); 122 | CollectionAssert.AreEqual(PptPageTitles, extractedPageTitles); 123 | } 124 | 125 | /// 126 | /// Validate the student notebook 127 | /// 128 | private static void ValidateStudentNotebook() 129 | { 130 | // retrieve xml from generated notebook 131 | var xmlDoc = _mOnGenerator.GetPageScopeHierarchy(_mStudentNotebookId); 132 | Assert.IsNotNull(xmlDoc); 133 | 134 | // retrieve the section for the ppt conversion 135 | string sectionName = Path.GetFileNameWithoutExtension(TestPptPath); 136 | XDocument xDoc = XDocument.Parse(xmlDoc); 137 | XElement xSection = xDoc.Descendants(_mXmlNs + "Section").FirstOrDefault(x => x.Attribute("name").Value.Equals(sectionName)); 138 | Assert.IsNotNull(xSection); 139 | 140 | //get the xml of each pages 141 | var extractedPageTitles = xSection.Descendants(_mXmlNs + "Page").Select(x => x.Attribute("name").Value).ToList(); 142 | CollectionAssert.AreEqual(PptPageTitles, extractedPageTitles); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/FormatReaders/EpubReaderUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using HtmlAgilityPack; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using OneNoteConversionTool.FormatReaders; 8 | 9 | namespace OneNoteConversionToolUnitTest.FormatReaders 10 | { 11 | [TestClass] 12 | public class EpubReaderUnitTest 13 | { 14 | private const string Title = "EpubSample"; 15 | private static readonly List PageTitles = new List() { "Epub Sample Cover", "Epub Sample TOC", "Epub Sample Page" }; 16 | private static readonly List PageLevels = new List() { 1, 1, 1}; 17 | 18 | private const string TestEpubFile = "..\\..\\Resources\\EpubSample.epub"; 19 | private static readonly string TestEpubPath = Path.Combine(Environment.CurrentDirectory, TestEpubFile); 20 | 21 | private static EpubReader _mEpubReader; 22 | 23 | /// 24 | /// Initializer method for the Unit Test 25 | /// 26 | /// 27 | [ClassInitialize()] 28 | public static void MyClassInitialize(TestContext testContext) 29 | { 30 | if (!Directory.Exists(Utility.RootFolder)) 31 | { 32 | Directory.CreateDirectory(Utility.RootFolder); 33 | } 34 | 35 | _mEpubReader = new EpubReader(TestEpubPath, Utility.RootFolder); 36 | } 37 | 38 | /// 39 | /// Cleanup: Delete temporary folders 40 | /// 41 | [ClassCleanup()] 42 | public static void MyClassCleanup() 43 | { 44 | //delete temporary folders 45 | if (Directory.Exists(Utility.RootFolder)) 46 | { 47 | Utility.DeleteDirectory(Utility.RootFolder); 48 | } 49 | } 50 | 51 | /// 52 | /// Validate Obtaining the title of the file 53 | /// 54 | [TestMethod] 55 | public void ValidateGetTitle() 56 | { 57 | string title = _mEpubReader.GetTitle(); 58 | Console.WriteLine(title); 59 | Assert.AreEqual(Title, title); 60 | } 61 | 62 | /// 63 | /// Validate obtaining the titles of the pages 64 | /// 65 | [TestMethod] 66 | public void ValidateGetPageTitles() 67 | { 68 | List titles = _mEpubReader.GetPageTitles(); 69 | CollectionAssert.AreEqual(PageTitles, titles); 70 | } 71 | 72 | /// 73 | /// Validate obtaining the pages html as HtmlDocument 74 | /// 75 | [TestMethod] 76 | public void ValidateGetPagesAsHtmlDocument() 77 | { 78 | List pagesHtml = _mEpubReader.GetPagesAsHtmlDocuments(); 79 | Assert.AreEqual(pagesHtml.Count, 3); 80 | } 81 | 82 | /// 83 | /// Validate obtaining the levels of all pages 84 | /// 85 | [TestMethod] 86 | public void ValidateGetPagesLevel() 87 | { 88 | Dictionary pageLevels = _mEpubReader.GetPagesLevel(); 89 | List pageLevelsList = (from int level in pageLevels.Values select level).ToList(); 90 | CollectionAssert.AreEqual(PageLevels, pageLevelsList); 91 | } 92 | 93 | /// 94 | /// Validate using non-existing input file 95 | /// 96 | [TestMethod] 97 | [ExpectedException(typeof(FileNotFoundException))] 98 | public void ValidateNonExistFile() 99 | { 100 | var epubReader = new EpubReader(Utility.NonExistentInputFile, Utility.RootFolder); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/FormatReaders/PowerPointOpenXmlUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using OneNoteConversionTool.FormatReaders; 6 | 7 | namespace OneNoteConversionToolUnitTest.FormatReaders 8 | { 9 | [TestClass] 10 | public class PowerPointOpenXmlUnitTest 11 | { 12 | private static readonly List PptPageTitles = new List() {"PresentationTitle", "DeletePage", "Third Slide", "PageTitle" }; 13 | private static readonly List PptNotes = new List() { "", "", "", "note\n" }; 14 | private static readonly List PptComments = new List() { "", "", "", "Author: Hichem Zakaria Aichour\nPageComment\n" }; 15 | private static readonly List PptSections = new List() { "MainSection", "FirstSection", "Some New Section", "SecondSection" }; 16 | private const int HiddenSlideNumber = 2; 17 | 18 | 19 | private const string TestPptFile = "..\\..\\Resources\\SectionSample.pptx"; 20 | private static readonly string TestPptPath = Path.Combine(Environment.CurrentDirectory, TestPptFile); 21 | 22 | private static PowerPointOpenXml _mPptOpenXml; 23 | 24 | /// 25 | /// Initializer method for the Unit Test 26 | /// 27 | /// 28 | [ClassInitialize()] 29 | public static void MyClassInitialize(TestContext testContext) 30 | { 31 | _mPptOpenXml = new PowerPointOpenXml(TestPptPath); 32 | } 33 | 34 | /// 35 | /// Validate obtaining slide titles 36 | /// 37 | [TestMethod] 38 | public void ValidateAllSlideTitles() 39 | { 40 | var titles = _mPptOpenXml.GetAllSlideTitles(); 41 | CollectionAssert.AreEqual(PptPageTitles, titles); 42 | } 43 | 44 | /// 45 | /// Validate obtaining slide notes 46 | /// 47 | [TestMethod] 48 | public void ValidateAllSlideNotes() 49 | { 50 | var notes = _mPptOpenXml.GetAllSlideNotes(); 51 | CollectionAssert.AreEqual(PptNotes, notes); 52 | } 53 | 54 | /// 55 | /// Validate obtaining slide comments 56 | /// 57 | [TestMethod] 58 | public void ValidateAllSlideComments() 59 | { 60 | var comments = _mPptOpenXml.GetAllSlideComments(); 61 | Console.WriteLine(comments[3]); 62 | Console.WriteLine(PptComments[3]); 63 | Console.WriteLine(comments[3]); 64 | CollectionAssert.AreEqual(PptComments, comments); 65 | } 66 | 67 | /// 68 | /// Validate detecting hidden slides 69 | /// 70 | [TestMethod] 71 | public void ValidateHiddenSlide() 72 | { 73 | Assert.IsTrue(_mPptOpenXml.IsHiddenSlide(HiddenSlideNumber)); 74 | } 75 | 76 | /// 77 | /// Validate obtaining section names 78 | /// 79 | [TestMethod] 80 | public void ValidateSectionNames() 81 | { 82 | var sections = _mPptOpenXml.GetSectionNames(); 83 | CollectionAssert.AreEqual(PptSections, sections); 84 | } 85 | 86 | /// 87 | /// Validate using non-existing input file 88 | /// 89 | [TestMethod] 90 | [ExpectedException(typeof(FileNotFoundException))] 91 | public void ValidateNonExistFile() 92 | { 93 | const string inputFile = Utility.NonExistentInputFile; 94 | var pptOpenXml = new PowerPointOpenXml(inputFile); 95 | 96 | var N = pptOpenXml.NumberOfSlides(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/OneNoteConversionToolUnitTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {86E7B739-1687-4475-B5AD-3989380C204B} 7 | Library 8 | Properties 9 | OneNoteConversionToolUnitTest 10 | OneNoteConversionToolUnitTest 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | True 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | ..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll 40 | 41 | 42 | False 43 | 44 | 45 | True 46 | 47 | 48 | True 49 | 50 | 51 | True 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | {df6efef6-1d0d-4b64-a425-0a3758f5c251} 89 | OneNoteConversionTool 90 | 91 | 92 | 93 | 94 | {0002E157-0000-0000-C000-000000000046} 95 | 5 96 | 3 97 | 0 98 | primary 99 | False 100 | True 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | False 113 | 114 | 115 | False 116 | 117 | 118 | False 119 | 120 | 121 | False 122 | 123 | 124 | 125 | 126 | 127 | 128 | 135 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/OutputGenerator/OneNoteGeneratorUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Xml.Linq; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | using OneNoteConversionTool.OutputGenerator; 10 | 11 | namespace OneNoteConversionToolUnitTest.OutputGenerator 12 | { 13 | [TestClass] 14 | public class OneNoteGeneratorUnitTest 15 | { 16 | private static XNamespace _mXmlNs; 17 | 18 | private static OneNoteGenerator _mOneNoteGenerator; 19 | 20 | private const string TestNotebookName = "TestNotebook"; 21 | private const string TestSectionName = "TestSection"; 22 | private const string TestPageName = "TestPage"; 23 | private static string _mTestNotebookDir = String.Empty; 24 | private static string _mTestNotebookId = String.Empty; 25 | private static string _mTestSectionId = String.Empty; 26 | private static string _mTestPageId = String.Empty; 27 | 28 | /// 29 | /// Initializes Test notebook for UnitTesting 30 | /// 31 | /// 32 | [ClassInitialize] 33 | public static void InitializeTestNotebook(TestContext testContext) 34 | { 35 | _mXmlNs = Utility.NS; 36 | 37 | _mTestNotebookDir = Path.GetTempPath(); 38 | 39 | _mOneNoteGenerator = new OneNoteGenerator(_mTestNotebookDir); 40 | _mTestNotebookId = _mOneNoteGenerator.CreateNotebook(TestNotebookName); 41 | _mTestSectionId = _mOneNoteGenerator.CreateSection(TestSectionName, _mTestNotebookId); 42 | //for ValidateCreateSectionNameConflicts() 43 | _mOneNoteGenerator.CreateSection(TestSectionName, _mTestNotebookId); 44 | _mOneNoteGenerator.CreateSection(TestSectionName, _mTestNotebookId); 45 | 46 | _mTestPageId = _mOneNoteGenerator.CreatePage(TestPageName, _mTestSectionId); 47 | 48 | //This is ugly, but apparently creating notebook/section/page takes time 49 | Thread.Sleep(4000); 50 | } 51 | 52 | /// 53 | /// Remove Test notebook that was created for UnitTesting 54 | /// 55 | [ClassCleanup] 56 | public static void CleanupTestNotebook() 57 | { 58 | if (Directory.Exists(_mTestNotebookDir + TestNotebookName)) 59 | Utility.DeleteDirectory(_mTestNotebookDir + TestNotebookName); 60 | } 61 | 62 | /// 63 | /// Validates create notebook method 64 | /// 65 | [TestMethod] 66 | public void ValidateCreateNotebook() 67 | { 68 | Assert.IsTrue(Directory.Exists(_mTestNotebookDir + TestNotebookName)); 69 | 70 | var notebookHierarchy = _mOneNoteGenerator.GetChildrenScopeHierarchy(_mTestNotebookId); 71 | Assert.IsNotNull(notebookHierarchy); 72 | 73 | XDocument xdoc = XDocument.Parse(notebookHierarchy); 74 | var node = xdoc.Elements(_mXmlNs + "Notebook") 75 | .Single(x => x.Attribute("name").Value.Equals(TestNotebookName)); 76 | 77 | Assert.IsNotNull(node); 78 | Assert.IsTrue(node.Attribute("name").Value.Equals(TestNotebookName)); 79 | Assert.IsTrue(node.Attribute("ID").Value.Equals(_mTestNotebookId)); 80 | } 81 | 82 | /// 83 | /// Validates create section method 84 | /// 85 | [TestMethod] 86 | public void ValidateCreateSection() 87 | { 88 | Assert.IsTrue(File.Exists(Path.Combine(_mTestNotebookDir, TestNotebookName, TestSectionName + ".one"))); 89 | 90 | var sectionHierarchy = _mOneNoteGenerator.GetSectionScopeHierarchy(_mTestNotebookId); 91 | Assert.IsNotNull(sectionHierarchy); 92 | 93 | var xdoc = XDocument.Parse(sectionHierarchy); 94 | var node = xdoc.Descendants(_mXmlNs + "Section") 95 | .Single(x => x.Attribute("name").Value.Equals(TestSectionName)); 96 | 97 | Assert.IsNotNull(node); 98 | Assert.IsTrue(node.Attribute("name").Value.Equals(TestSectionName)); 99 | Assert.IsTrue(node.Attribute("ID").Value.Equals(_mTestSectionId)); 100 | } 101 | 102 | /// 103 | /// Validate CreateSection() when section name already exist 104 | /// 105 | [TestMethod] 106 | public void ValidateCreateSectionNameConflicts() 107 | { 108 | var sectionHierarchy = _mOneNoteGenerator.GetSectionScopeHierarchy(_mTestNotebookId); 109 | Assert.IsNotNull(sectionHierarchy); 110 | 111 | var xdoc = XDocument.Parse(sectionHierarchy); 112 | 113 | const string testSectionName2 = TestSectionName + " (2)"; 114 | const string testSectionName3 = TestSectionName + " (3)"; 115 | var expectedSectionNames = new List() 116 | { 117 | TestSectionName, 118 | testSectionName2, 119 | testSectionName3 120 | }; 121 | var sectionNames = xdoc.Descendants(_mXmlNs + "Section").Select(x => x.Attribute("name").Value).ToList(); 122 | CollectionAssert.AreEqual(expectedSectionNames, sectionNames); 123 | } 124 | 125 | /// 126 | /// Validates create section method 127 | /// 128 | [TestMethod] 129 | public void ValidateCreatePage() 130 | { 131 | var pageHierarchy = _mOneNoteGenerator.GetChildrenScopeHierarchy(_mTestPageId); 132 | Assert.IsNotNull(pageHierarchy); 133 | 134 | XDocument xdoc = XDocument.Parse(pageHierarchy); 135 | var node = xdoc.Elements(_mXmlNs + "Page") 136 | .Single(x => x.Attribute("name").Value.Equals(TestPageName)); 137 | 138 | Assert.IsNotNull(node); 139 | Assert.IsTrue(node.Attribute("name").Value.Equals(TestPageName)); 140 | Assert.IsTrue(node.Attribute("ID").Value.Equals(_mTestPageId)); 141 | } 142 | 143 | /// 144 | /// Validates Unescape XML function 145 | /// 146 | [TestMethod] 147 | public void ValidateUnescapeXml() 148 | { 149 | string doc = "'"test><&"; 150 | const string expected = "'\"test><&"; 151 | string actual = OneNoteConversionTool.Utility.UnescapeXml(doc); 152 | 153 | Assert.AreEqual(expected, actual); 154 | } 155 | 156 | /// 157 | /// Validates Create Table of Content Page function 158 | /// 159 | [TestMethod] 160 | public void ValidateCreateTableOfContentPage() 161 | { 162 | const string tocPageTitle = "Test Table of Content"; 163 | var tocPageId = _mOneNoteGenerator.CreateTableOfContentPage(_mTestSectionId, tocPageTitle); 164 | 165 | var sectionHierarchy = _mOneNoteGenerator.GetChildrenScopeHierarchy(_mTestSectionId); 166 | Assert.IsNotNull(sectionHierarchy); 167 | 168 | XDocument xdoc = XDocument.Parse(sectionHierarchy); 169 | var node = xdoc.Elements(_mXmlNs + "Section") 170 | .Single(x => x.Attribute("name").Value.Equals(TestSectionName)) 171 | .Elements(_mXmlNs + "Page") 172 | .Single(x => x.Attribute("ID").Value.Equals(tocPageId)); 173 | 174 | Assert.IsNotNull(node); 175 | Assert.IsTrue(node.Attribute("name").Value.Equals(tocPageTitle)); 176 | Assert.IsTrue(node.Attribute("ID").Value.Equals(tocPageId)); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("OneNoteConversionToolUnitTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("OneNoteConversionToolUnitTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("060ec9b4-550f-472a-8c70-88a2f4e61d3a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/Resources/EpubSample.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OneNoteDev/OneNoteConversionTool/7022a7808ccc30204c384664fa2e01ce31d5a46c/OneNoteConversionToolUnitTest/Resources/EpubSample.epub -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/Resources/SectionSample.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OneNoteDev/OneNoteConversionTool/7022a7808ccc30204c384664fa2e01ce31d5a46c/OneNoteConversionToolUnitTest/Resources/SectionSample.pptx -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace OneNoteConversionToolUnitTest 5 | { 6 | /// 7 | /// Class that contains a bunch of helper methods for UnitTesting 8 | /// 9 | public class Utility 10 | { 11 | public const string NS = "http://schemas.microsoft.com/office/onenote/2013/onenote"; 12 | public const string TempFolder = @"C:\onetest\temporary"; 13 | public const string RootFolder = @"C:\onetest"; 14 | public const string NonExistentInputFile = @"C:\thisFileDontExist"; 15 | public const string NonExistentOutputPath = @"C:\invalidOutputDir"; 16 | 17 | 18 | #region Helper methods 19 | /// 20 | /// Helper method to delete entire folder and files 21 | /// 22 | /// 23 | public static bool DeleteDirectory(string targetDir) 24 | { 25 | try 26 | { 27 | Directory.Delete(targetDir, true); 28 | } 29 | catch 30 | { 31 | Console.WriteLine("Failed to delete directory: " + targetDir); 32 | return false; 33 | } 34 | 35 | return true; 36 | } 37 | #endregion 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /OneNoteConversionToolUnitTest/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OneNoteConversionTool 2 | 3 | This is a Windows Application for converting documents of various formats into OneNote. 4 | 5 | Currently supported formats: 6 | - Microsoft Word (.doc, .docx, .dot, .dotx, .docm, .dotm, .odt) 7 | - Microsoft PowerPoint (.ppt, .pptx, .pot, .potx, .pptm, .potm, .odp) 8 | - PDF (.pdf) 9 | - Epub (.epub) 10 | - InDesign Document (.indd) 11 | 12 | ## How to open 13 | 14 | Open the OneNoteConversionTool.sln file in Visual Studio 2013 or later. 15 | 16 | In order to compile, you will need: 17 | - Microsoft Word 2013 installed 18 | - Microsoft PowerPoint 2013 installed 19 | 20 | If you would like to add support for InDesign documents, you need to: 21 | - have Adobe InDesign installed 22 | - define `INDESIGN_INSTALLED` in the compiler options 23 | -------------------------------------------------------------------------------- /packages/epubReader.1.0.0/epubReader.1.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OneNoteDev/OneNoteConversionTool/7022a7808ccc30204c384664fa2e01ce31d5a46c/packages/epubReader.1.0.0/epubReader.1.0.0.nupkg -------------------------------------------------------------------------------- /packages/epubReader.1.0.0/lib/net40/eBdb.EpubReader.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OneNoteDev/OneNoteConversionTool/7022a7808ccc30204c384664fa2e01ce31d5a46c/packages/epubReader.1.0.0/lib/net40/eBdb.EpubReader.dll --------------------------------------------------------------------------------