Skip to content

Commit

Permalink
Merge pull request #104 from alxnbl/dev-150
Browse files Browse the repository at this point in the history
Version 1.5.0
  • Loading branch information
alxnbl authored Jun 14, 2024
2 parents b22c5ea + a7f3f80 commit 5244f8a
Show file tree
Hide file tree
Showing 33 changed files with 806 additions and 550 deletions.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
This tool is usefull to :
* evaluate or migrate to an alternative Knowledge Management Software like Joplin, Obsidian or other softwares based on Markdown format
* backup your OneNote Notebooks in an interoperable and open file format


The tool is easy to install and use, and generally produces better results than other OneNote export methods.

# Requirements

- Windows >=10
Expand Down Expand Up @@ -50,7 +52,7 @@ Command line is supported, run `OneNoteMdExporter.exe --help` for instructions.
---
Page content
```
* `PanDocMarkdownFormat` : choose the markdown syntax to use among [those supported by pandoc](https://pandoc.org/MANUAL.html#general-options). Use *Github flavor* by default.
* `PanDocMarkdownFormat` : choose the markdown syntax to use among [those supported by pandoc](https://pandoc.org/MANUAL.html#general-options). Use *GitHub flavor* by default.

## Joplin Raw Directory

Expand All @@ -61,7 +63,7 @@ Command line is supported, run `OneNoteMdExporter.exe --help` for instructions.

| Export format: | Markdown | Joplin |
| --- | --- | --- |
| Hierarchy of sections | ✅ Folder hierarchy | ✅ Notbook hierarchy |
| Hierarchy of sections | ✅ Folder hierarchy | ✅ Notebook hierarchy |
| Page ordering inside a section | 🔴 Ordering based on md filename | ✅ |
| Page hierarchy | ✅ Page prefix or folder prefix | ✅ |

Expand All @@ -71,17 +73,17 @@ ___

| All formats : | |
| --- | --- |
| Attachments | 🟠 File of certain extensions are lost (wma, wmv, mpg, svg, mp3) |
| Attachments | |
| Image | ✅ |
| Table | ✅ |
| Image nexted into table | 🔴 Known issue (#48) |
| Folded paragraphs | ✅ |
| Image nexted into table | 🔴 Known issue [#48](https://github.com/alxnbl/onenote-md-exporter/issues/48) |
| Font color| 🔴 |
| Background color | 🟠 Highlighted text |
| Drawing | 🟠 Flattened as image |
| Handwriting | 🔴 Lost |
| Text tags (task, star...) | 🔴 Lost |
| Password protected sections | 🟠 Lost unless unlocked before export |
| Folded pargraphs | 🔴 Lost |
| Notebook internal link | 🔴 onenote:// url |

# Technical characteristics
Expand All @@ -90,7 +92,8 @@ ___
* Export page as DocX and translate them in Markdown using PanDoc
* Offline : no call to Microsoft cloud
* Based on Office Interop APIs
* Apply some post-processing based on Regex to correct formatting issues
* Pre-processing stage of OneNote page XML structure
* Post-processing stage based on Regex to fix formatting issues

# Licence

Expand Down
4 changes: 2 additions & 2 deletions doc/contribute.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Add a new Export setting

- Add the setting in [AppSettings.cs](/src/OneNoteMdExporter/Infrastructure/AppSettings.cs) with a description
- Add the setting in [appsettings.json](/src/OneNoteMdExporter/appsettings.json) with a description
- Use your settings in ExportServiceBase.cs / JoplinExportService or MdExportService using the `_appSettings` field
- Add the setting in [appSettings.json](/src/OneNoteMdExporter/appSettings.json) with a description
- Use your settings in ExportServiceBase.cs / JoplinExportService or MdExportService using the `AppSettings` class

# Add a new langage to translations

Expand Down
4 changes: 2 additions & 2 deletions doc/migration-to-joplin.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ One of the objectives of this tool it to offer the most simple and lossless solu
| Password protected sections | 🔴 Lost | 🔴 Lost |
| Notebook internal link | 🔴 onenote:// url | 🔴 onenote:// url |

(\*1) : setting `ProcessingOfPageHierarchy = HiearchyAsFolderTree` (default)<br />
(\*2) : setting `ProcessingOfPageHierarchy = HiearchyAsPageTitlePrefix`
(\*1) : setting `ProcessingOfPageHierarchy = HierarchyAsFolderTree` (default)<br />
(\*2) : setting `ProcessingOfPageHierarchy = HierarchyAsPageTitlePrefix`

# User guide

Expand Down
3 changes: 2 additions & 1 deletion doc/publish-new-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
1. Update `Package version` of `OneNoteMdExporter` project to the desired software version.
3. Ensure PanDoc archive has beed unzipped in folder `src\OneNoteMdExporter\pandoc`
3. From Visual Studio, use Publish profile of `OneNoteMdExporter` project to build the tool binaries
4. Open output folder (`bin\Release\net5.0\win7-x86\publish`) and Zip the content of the folder and name it `OneNoteMdExporter.vX.Y.Z.zip`
4. Open output folder (`bin\Release\net8.0\win-x86\publish\win-x64`) and Zip the content of the folder and name it `OneNoteMdExporter.vX.Y.Z.zip`
5. Go into Releases, create a tag "vX.Y.Z" and create a release "vX.Y.Z"
Binary file modified sample/TestNotebook.onepkg
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>
Expand All @@ -19,9 +19,9 @@

<ItemGroup>
<!-- COMReference of OneNoteMdExporter not yet supported by DotNet5 -->
<PackageReference Include="NUnit" Version="4.0.1" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/OneNoteMdExporter.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30804.86
# Visual Studio Version 17
VisualStudioVersion = 17.9.34723.18
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OneNoteMdExporter", "OneNoteMdExporter\OneNoteMdExporter.csproj", "{3D5886DD-752E-48FB-BC28-8F37F3298948}"
EndProject
Expand Down
81 changes: 18 additions & 63 deletions src/OneNoteMdExporter/Helpers/OneNoteExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Microsoft.Office.Interop.OneNote;
using alxnbl.OneNoteMdExporter.Infrastructure;
using alxnbl.OneNoteMdExporter.Models;
using Microsoft.Office.Interop.OneNote;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using alxnbl.OneNoteMdExporter.Infrastructure;

namespace alxnbl.OneNoteMdExporter.Helpers
{
Expand All @@ -27,7 +27,7 @@ public static IList<Notebook> GetNotebooks(this Application oneNoteApp)
CreationDate = element.GetDate("lastModifiedTime"),
LastModificationDate = element.GetDate("lastModifiedTime")
};
}).ToList();
}).Where(element => element.Title != TemporaryNotebook.Title).ToList();
}

public static DateTime GetDate(this XElement element, string attributeName)
Expand All @@ -47,37 +47,29 @@ public static Section GetSection(this XElement element, Node parentNode)
OneNoteId = element.Attribute("ID")?.Value,
OneNotePath = element.Attribute("path")?.Value,
CreationDate = element.GetDate("lastModifiedTime"),
LastModificationDate = element.GetDate("lastModifiedTime")
LastModificationDate = element.GetDate("lastModifiedTime"),
IsSectionGroup = element.Name.LocalName switch
{
"SectionGroup" => true,
"Section" => false,
_ => throw new NotImplementedException(),
}
};

switch (element.Name.LocalName)
{
case "SectionGroup":
section.IsSectionGroup = true;
break;
case "Section":
section.IsSectionGroup = false;
break;
default:
throw new NotImplementedException();

}

return section;
}

public static Page GetPage(this XElement element, Section parentSection, AppSettings appSettings)
public static Page GetPage(this XElement element, Section parentSection)
{
var pageId = element.Attribute("ID")?.Value;

DateTime.TryParse(element.Attribute("dateTime").Value, out var creationDate);
DateTime.TryParse(element.Attribute("lastModifiedTime").Value, out var lastModificationDate);
int.TryParse(element.Attribute("pageLevel").Value, out var pageLevel);
_ = DateTime.TryParse(element.Attribute("dateTime").Value, out var creationDate);
_ = DateTime.TryParse(element.Attribute("lastModifiedTime").Value, out var lastModificationDate);
_ = int.TryParse(element.Attribute("pageLevel").Value, out var pageLevel);

var title = element.Attribute("name").Value;

// Limit title max size, especilay for notes with no title where the 1st paragraphe is returned as a title
if (title.Length > appSettings.PageTitleMaxLength)
// Limit title max size, especially for notes with no title where the 1st paragraph is returned as a title
if (title.Length > AppSettings.PageTitleMaxLength)
title = new string(title.Take(50).ToArray()) + "...";

var page = new Page(parentSection)
Expand Down Expand Up @@ -133,7 +125,7 @@ private static void FillNodebookSections(Node node, XElement xmlNode)
/// </summary>
/// <param name="section"></param>
/// <returns>List of pages</returns>
public static IList<Page> FillSectionPages(this Application oneNoteApp, Section section, AppSettings appSettings)
public static IList<Page> FillSectionPages(this Application oneNoteApp, Section section)
{
oneNoteApp.GetHierarchy(section.OneNoteId, HierarchyScope.hsPages, out var xmlStr);
var xmlSection = XDocument.Parse(xmlStr).Root;
Expand All @@ -142,7 +134,7 @@ public static IList<Page> FillSectionPages(this Application oneNoteApp, Section
var xmlPages = xmlSection.Descendants(ns + "Page")
.Where(e => e.Attribute("isRecycleBin") == null && e.Attribute("isDeletedPages") == null);

var childPages = xmlPages.Select(xmlP => xmlP.GetPage(section, appSettings)).ToList();
var childPages = xmlPages.Select(xmlP => xmlP.GetPage(section)).ToList();

Page pageL1Cursor = null;
Page pageL2Cursor = null;
Expand All @@ -167,47 +159,10 @@ public static IList<Page> FillSectionPages(this Application oneNoteApp, Section
page.SetParentPage(pageL2Cursor ?? pageL1Cursor); // If page level 3 under a page level 1
}

oneNoteApp.GetPageContent(page.OneNoteId, out var xmlPageContentStr, PageInfo.piAll);


// Alternative : return page content without binaries
//oneNoteApp.GetHierarchy(page.OneNoteId, HierarchyScope.hsChildren, out var xmlAttach);

var xmlPageContent = XDocument.Parse(xmlPageContentStr).Root;

var ns2 = xmlPageContent.Name.Namespace;
var pageTitleOE = xmlPageContent.Descendants(ns + "Title")?.FirstOrDefault()?.Descendants(ns + "OE")?.FirstOrDefault();
if (pageTitleOE != null)
{
page.Author = pageTitleOE.Attribute("author")?.Value ?? "unknown";
}

section.Childs.Add(page);

ProcessPageAttachments(ns, page, xmlPageContent);
}


return childPages;
}

private static void ProcessPageAttachments(XNamespace ns, Page page, XElement xmlPageContent)
{
foreach (var xmlInsertedFile in xmlPageContent.Descendants(ns + "InsertedFile"))
{
var fileAttachment = new Attachement(page)
{
ActualSourceFilePath = xmlInsertedFile.Attribute("pathCache")?.Value,
OriginalUserFilePath = xmlInsertedFile.Attribute("pathSource")?.Value,
OneNotePreferredFileName = xmlInsertedFile.Attribute("preferredName")?.Value,
Type = AttachementType.File
};

if (fileAttachment.ActualSourceFilePath != null)
{
page.Attachements.Add(fileAttachment);
}
}
}
}
}
2 changes: 1 addition & 1 deletion src/OneNoteMdExporter/Helpers/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static string RemoveMdReferenceInvalidChars(this string reference)
=> reference?.Replace(" ", "_");

public static string Left(this String input, int length)
=> (input.Length < length) ? input : input.Substring(0, length);
=> (input.Length < length) ? input : input[..length];

}
}
Loading

0 comments on commit 5244f8a

Please sign in to comment.