1param([Parameter(Mandatory=$true)][string]$Root)
2Set-StrictMode -Version Latest
3$ErrorActionPreference = 'Stop'
4$notebook = Join-Path $Root 'notebook'
5$app = New-Object -ComObject OneNote.Application
6try {
7 $hierarchy = ''
8 $app.GetHierarchy('', 4, [ref]$hierarchy, 1)
9 [xml]$tree = $hierarchy
10 $page = $tree.SelectSingleNode('//*[local-name()="Notebook"][@path="' + $notebook + '"]//*[local-name()="Page"]')
11 if (-not $page) { throw 'The notebook has no page open.' }
12 $content = ''
13 $app.GetPageContent($page.GetAttribute('ID'), [ref]$content, 0, 1)
14 [IO.File]::WriteAllText((Join-Path $Root 'before.xml'), $content, [Text.Encoding]::UTF8)
15 [xml]$xml = $content
16 # OneNote edits the tagged paragraphs: new text on one, the check box of another cleared.
17 foreach ($oe in $xml.SelectNodes('//*[local-name()="OE"]')) {
18 $text = $oe.SelectSingleNode('*[local-name()="T"]')
19 if (-not $text) { continue }
20 if ($text.InnerText -eq 'Launch day') { $text.InnerXml = '<![CDATA[Launch day, moved to Friday]]>' }
21 if ($text.InnerText -eq 'Checked off') {
22 foreach ($tag in $oe.SelectNodes('*[local-name()="Tag"]')) { $tag.SetAttribute('completed', 'false') }
23 }
24 }
25 [IO.File]::WriteAllText((Join-Path $Root 'update.xml'), $xml.OuterXml, [Text.Encoding]::UTF8)
26 $app.UpdatePageContent($xml.OuterXml, [DateTime]::MinValue, 1, $false)
27 $id = $tree.SelectSingleNode('//*[local-name()="Notebook"][@path="' + $notebook + '"]').GetAttribute('ID')
28 $app.SyncHierarchy($id)
29 Start-Sleep -Seconds 5
30} finally {
31 [void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($app)
32 [GC]::Collect()
33 [GC]::WaitForPendingFinalizers()
34}
35# What OneNote left of Snowbound's folder: its attribute, and each file with its hash.
36$folder = Get-Item -LiteralPath (Join-Path $notebook '.snowbound') -Force
37$files = @(Get-ChildItem -LiteralPath $folder.FullName -Recurse -Force | ForEach-Object {
38 $hash = $null
39 if (-not $_.PSIsContainer) { $hash = (Get-FileHash -Algorithm SHA256 -LiteralPath $_.FullName).Hash.ToLower() }
40 @{ path = $_.FullName.Substring($folder.FullName.Length + 1).Replace('\', '/');
41 attributes = $_.Attributes.ToString(); sha256 = $hash }
42})
43@{ attributes = $folder.Attributes.ToString(); files = $files;
44 notebook = @(Get-ChildItem -LiteralPath $notebook -Force | ForEach-Object { $_.Name }) } |
45 ConvertTo-Json -Depth 4 | Set-Content (Join-Path $Root 'sidecar.json') -Encoding UTF8