diff --git a/ConvertOneNote2MarkDown-v2.Tests.ps1 b/ConvertOneNote2MarkDown-v2.Tests.ps1
index 72d1ae7..8645573 100644
--- a/ConvertOneNote2MarkDown-v2.Tests.ps1
+++ b/ConvertOneNote2MarkDown-v2.Tests.ps1
@@ -313,6 +313,24 @@ Describe "Truncate-PathFileName" -Tag 'Unit' {
$path | Truncate-PathFileName -Length $length | Should -Be $expectedPath
}
+ It "Should keep a given -KeepSuffix when truncating" {
+ $drive = "C:$( [io.path]::DirectorySeparatorChar )" # E.g. C:\
+ $path = $drive + ("a" * 1000) + '-1'
+ $length = 123
+ $expectedPath = $drive + ("a" * 121) + '-1'
+
+ $path | Truncate-PathFileName -Length $length -KeepSuffix '-1' | Should -Be $expectedPath
+ }
+
+ It "Should ignore -KeepSuffix if the filename does not end with it" {
+ $drive = "C:$( [io.path]::DirectorySeparatorChar )" # E.g. C:\
+ $path = $drive + ("a" * 1000)
+ $length = 123
+ $expectedPath = $drive + ("a" * 123)
+
+ $path | Truncate-PathFileName -Length $length -KeepSuffix '-1' | Should -Be $expectedPath
+ }
+
}
}
@@ -833,6 +851,32 @@ Describe 'New-SectionGroupConversionConfig' -Tag 'Unit' {
}
}
+ It "Should not match an attachment's name inside a longer attachment name" {
+ Mock Get-OneNotePageContent {
+ @'
+
+
+
+
+
+
+
+
+
+'@ -as [xml]
+ }
+
+ $pageCfg = @( New-SectionGroupConversionConfig @params 6>$null ) | Select-Object -First 1
+ $content = '\<\\> and \<\<11-36-00002.pdf\>\>'
+ foreach ($m in ($pageCfg['mutations'] | Where-Object { $_['description'] -eq 'Change inserted attachment(s) filename references' })) {
+ foreach ($r in $m['replacements']) {
+ $content = $content -replace $r['searchRegex'], $r['replacement']
+ }
+ }
+
+ $content | Should -Be "\<\<[Datenblatt_11-36-00002.pdf]($( $pageCfg['mediaPathPandoc'] )/Datenblatt_11-36-00002.pdf)\>\> and \<\<[11-36-00002.pdf]($( $pageCfg['mediaPathPandoc'] )/11-36-00002.pdf)\>\>"
+ }
+
It "Should generate fully unique docx file for each page, even for identically-named pages in a section" {
$result = @( New-SectionGroupConversionConfig @params 6>$null )
@@ -885,6 +929,34 @@ Describe 'New-SectionGroupConversionConfig' -Tag 'Unit' {
}
}
+ It "Should keep the unique postfix of identically named pages when truncating long names" {
+ $longName = 'Some long name ' * 20
+ $fakeHierarchy = @"
+
+
+
+
+
+
+
+
+
+
+"@ -as [xml]
+ $params['SectionGroups'] = $fakeHierarchy.Notebooks.Notebook
+ $params['Config']['mdFileNameAndFolderNameMaxLength']['value'] = 100
+
+ $result = @( New-SectionGroupConversionConfig @params 6>$null )
+
+ $result.Count | Should -Be 3
+ $result[1]['fileName'] | Should -Match '-1\.md$'
+ $result[2]['fileName'] | Should -Match '-2\.md$'
+ @( $result | ForEach-Object { $_['filePathNormal'] } | Select-Object -Unique ).Count | Should -Be 3
+ foreach ($pageCfg in $result) {
+ $pageCfg['fileName'].Length | Should -BeLessOrEqual 100
+ }
+ }
+
It "Should honor config notesdestpath" {
if ($env:OS -match 'windows') {
$params['Config']['notesdestpath']['value'] = 'D:\foo\bar'
diff --git a/ConvertOneNote2MarkDown-v2.ps1 b/ConvertOneNote2MarkDown-v2.ps1
index 3668cba..bb5a62e 100644
--- a/ConvertOneNote2MarkDown-v2.ps1
+++ b/ConvertOneNote2MarkDown-v2.ps1
@@ -386,6 +386,11 @@ Function Truncate-PathFileName {
[ValidateRange(0,255)]
[int]
$Length
+ ,
+ # A suffix (e.g. the '-1' postfix of a duplicate page name) that must survive truncation
+ [Parameter()]
+ [string]
+ $KeepSuffix = ''
)
process {
@@ -404,7 +409,11 @@ Function Truncate-PathFileName {
$name = Split-Path $Path -Leaf
if ($name.Length -gt $maxLength) {
$parent = Split-Path $Path -Parent
- $truncatedName = $name.Substring(0, $maxLength)
+ $truncatedName = if ($KeepSuffix -and $name.EndsWith($KeepSuffix) -and $maxLength -gt $KeepSuffix.Length) {
+ $name.Substring(0, $maxLength - $KeepSuffix.Length) + $KeepSuffix
+ }else {
+ $name.Substring(0, $maxLength)
+ }
[io.path]::combine( $parent, $truncatedName )
}else {
$Path
@@ -800,17 +809,18 @@ Function New-SectionGroupConversionConfig {
$pageCfg['filePathRel'] = & {
$filePathRel = "$( $pageCfg['pagePrefix'] )$( $pageCfg['nameCompat'] )"
- # in case multiple pages with the same name exist in a section, postfix the filename
+ # In case multiple pages with the same name exist in a section, postfix the filename.
+ # Compare the names as they will be written (truncated to fit '.md'), so two long names that only differ
+ # after the cut-off are also recognized as duplicates. The postfix is kept when truncating below, so it can't be cut off again.
+ $pageCfg['filePathRelKey'] = $filePathRel | Truncate-PathFileName -Length ($config['mdFileNameAndFolderNameMaxLength']['value'] - 3)
$recurrence = 0
foreach ($p in $sectionCfg['pages']) {
- if ($p['pagePrefix'] -eq $pageCfg['pagePrefix'] -and $p['pathFromRoot'] -eq $pageCfg['pathFromRoot']) {
+ if ($p['filePathRelKey'] -eq $pageCfg['filePathRelKey']) {
$recurrence++
}
}
- if ($recurrence -gt 0) {
- $filePathRel = "$filePathRel-$recurrence"
- }
- $filePathRel | Truncate-PathFileName -Length $config['mdFileNameAndFolderNameMaxLength']['value'] # Truncate to no more than 255 characters so we don't hit the folder name limit on most file systems on Windows / Linux
+ $pageCfg['filePathRelPostfix'] = if ($recurrence -gt 0) { "-$recurrence" } else { '' }
+ "$filePathRel$( $pageCfg['filePathRelPostfix'] )" | Truncate-PathFileName -Length $config['mdFileNameAndFolderNameMaxLength']['value'] -KeepSuffix $pageCfg['filePathRelPostfix'] # Truncate to no more than 255 characters so we don't hit the folder name limit on most file systems on Windows / Linux
}
$pageCfg['filePathRelUnderscore'] = $pageCfg['filePathRel'].Replace( [io.path]::DirectorySeparatorChar, '_' )
$pageCfg['filePathNormal'] = & {
@@ -819,7 +829,7 @@ Function New-SectionGroupConversionConfig {
}else {
[io.path]::combine( $cfg['notesDirectory'], $sectionCfg['nameCompat'], "$( $pageCfg['filePathRel'] )" )
}
- "$( $pathWithoutExtension | Truncate-PathFileName -Length ($config['mdFileNameAndFolderNameMaxLength']['value'] - 3) ).md" # Truncate to no more than 255 characters so we don't hit the file name limit on Windows / Linux
+ "$( $pathWithoutExtension | Truncate-PathFileName -Length ($config['mdFileNameAndFolderNameMaxLength']['value'] - 3) -KeepSuffix $pageCfg['filePathRelPostfix'] ).md" # Truncate to no more than 255 characters so we don't hit the file name limit on Windows / Linux
}
$pageCfg['filePathLong'] = "\\?\$( $pageCfg['filePathNormal'] )" # A non-Win32 path. Prefixing with '\\?\' allows Windows Powershell <= 5 (based on Win32) to support long absolute paths.
$pageCfg['filePath'] = if ($PSVersionTable.PSVersion.Major -le 5) {
@@ -896,7 +906,9 @@ Function New-SectionGroupConversionConfig {
description = 'Change inserted attachment(s) filename references'
replacements = @(
@{
- searchRegex = [regex]::Escape( $attachmentCfg['object'].preferredName )
+ # Only where the name is not part of a longer file name: with attachments '11-36-00002.pdf' and 'Datenblatt_11-36-00002.pdf'
+ # on one page, a plain search for the first one also matched inside the second, nesting one link inside the other
+ searchRegex = '(?