diff --git a/ConvertOneNote2MarkDown-v2.Tests.ps1 b/ConvertOneNote2MarkDown-v2.Tests.ps1 index 72d1ae7..c12496a 100644 --- a/ConvertOneNote2MarkDown-v2.Tests.ps1 +++ b/ConvertOneNote2MarkDown-v2.Tests.ps1 @@ -885,6 +885,27 @@ Describe 'New-SectionGroupConversionConfig' -Tag 'Unit' { } } + It "Should generate unique media file names for each page, even for subpages and identically-named pages of a Section" { + foreach ($medialocation in 1, 2) { + $params['Config']['medialocation']['value'] = $medialocation + foreach ($fakeHierarchy in @( (Get-FakeOneNoteHierarchy), (Get-FakeOneNoteHierarchyWithDuplicatePageNames) )) { + $params['SectionGroups'] = $fakeHierarchy.Notebooks.Notebook + $result = @( New-SectionGroupConversionConfig @params 6>$null ) + + # Media file names must be unique within each media folder + $result | Group-Object { [io.path]::combine( $_['mediaPath'], $_['mediaNamePrefix'] ) } | Where-Object { $_.Count -gt 1 } | ForEach-Object { $_.Name } | Should -Be $null + } + } + + # Media file names of first level pages that are not identically-named are unchanged + $params['Config']['medialocation']['value'] = 1 + $params['SectionGroups'] = (Get-FakeOneNoteHierarchy).Notebooks.Notebook + $result = @( New-SectionGroupConversionConfig @params 6>$null ) + foreach ($pageCfg in @( $result | Where-Object { $_['pageLevel'] -eq 1 } )) { + $pageCfg['mediaNamePrefix'] | Should -Be $pageCfg['pathFromRootCompat'] + } + } + It "Should honor config notesdestpath" { if ($env:OS -match 'windows') { $params['Config']['notesdestpath']['value'] = 'D:\foo\bar' @@ -1760,14 +1781,15 @@ Describe 'Convert-OneNotePage' -Tag 'Unit' { Assert-MockCalled -CommandName Get-ChildItem -Times 1 -Scope It Assert-MockCalled -CommandName Move-Item -Times 1 -Scope It + Assert-MockCalled -CommandName Move-Item -ParameterFilter { (Split-Path $Destination -Leaf) -eq "$( $params['ConversionConfig']['mediaNamePrefix'] )-image.jpg" } -Times 1 -Scope It } - It "Does not halt conversion if renaming image(s) fails" { + It "Does not halt conversion if renaming image(s) fails, and reports the image's destination path" { Mock Move-Item { throw } $err = Convert-OneNotePage @params 6>$null 2>&1 - $err.Exception.Message | Select-Object -First 1 | Should -match 'Failed to rename image' + $err.Exception.Message | Select-Object -First 1 | Should -match "Failed to rename image .+ to $( [regex]::Escape([io.path]::combine( $params['ConversionConfig']['mediaPath'], "$( $params['ConversionConfig']['mediaNamePrefix'] )-image.jpg" )) )\." } It "Markdown Mutation: Rename page image references in markdown to unique names" { diff --git a/ConvertOneNote2MarkDown-v2.ps1 b/ConvertOneNote2MarkDown-v2.ps1 index 3668cba..a07ce22 100644 --- a/ConvertOneNote2MarkDown-v2.ps1 +++ b/ConvertOneNote2MarkDown-v2.ps1 @@ -861,6 +861,12 @@ Function New-SectionGroupConversionConfig { $cfg['notesBaseDirectory'] } $pageCfg['mediaPath'] = [io.path]::combine( $pageCfg['mediaParentPath'], 'media' ) + $pageCfg['mediaNamePrefix'] = if ($config['medialocation']['value'] -eq 2) { + $pageCfg['filePathRelUnderscore'] + }else { + # The media of all of a notebook's pages are saved in the same folder, so the prefix includes the page's parent pages and the postfix of identically-named pages, i.e. the .md file's path. Or else e.g. subpages with the same name would overwrite each other's media + "$( $sectionCfg['pathFromRoot'] )$( [io.path]::DirectorySeparatorChar )$( $pageCfg['filePathRel'] )" | Remove-InvalidFileNameChars + } $pageCfg['mediaParentPathPandoc'] = [io.path]::combine( $pageCfg['tmpPath'] ).Replace( [io.path]::DirectorySeparatorChar, '/' ) # Pandoc outputs paths in markdown with with front slahes after the supplied , e.g. '/media/image.png'. So let's use a front-slashed supplied mediaPath $pageCfg['mediaPathPandoc'] = [io.path]::combine( $pageCfg['tmpPath'], 'media').Replace( [io.path]::DirectorySeparatorChar, '/' ) # Pandoc outputs paths in markdown with with front slahes after the supplied , e.g. '/media/image.png'. So let's use a front-slashed supplied mediaPath $pageCfg['docxExportFilePath'] = if ($config['docxNamingConvention']['value'] -eq 1) { @@ -1241,18 +1247,14 @@ Function Convert-OneNotePage { foreach ($image in $images) { # Rename Image try { - $newimageName = if ($config['medialocation']['value'] -eq 2) { - "$( $pageCfg['filePathRelUnderscore'] )-$($image.BaseName)$($image.Extension)" - }else { - "$( $pageCfg['pathFromRootCompat'] )-$($image.BaseName)$($image.Extension)" - } + $newimageName = "$( $pageCfg['mediaNamePrefix'] )-$($image.BaseName)$($image.Extension)" $newimagePath = [io.path]::combine( $pageCfg['mediaPath'], $newimageName ) "Moving image: $( $image.FullName ) to $( $newimagePath )" | Write-Verbose if (!$config['dryRun']['value']) { $item = Move-Item -Path "$( $image.FullName )" -Destination $newimagePath -Force -ErrorAction Stop -PassThru } }catch { - Write-Error "Failed to rename image $( $image.FullName ) to $( $item.FullName ). Exception: $( $_.Exception.Message )" -ErrorAction Continue + Write-Error "Failed to rename image $( $image.FullName ) to $( $newimagePath ). Exception: $( $_.Exception.Message )" -ErrorAction Continue } # Mutate markdown content with new image references try {