Skip to content

Instantly share code, notes, and snippets.

@HighLibrarian
Created May 14, 2024 13:02
Show Gist options
  • Select an option

  • Save HighLibrarian/10e718f3f84fe6bd6103d7bc4d04b37b to your computer and use it in GitHub Desktop.

Select an option

Save HighLibrarian/10e718f3f84fe6bd6103d7bc4d04b37b to your computer and use it in GitHub Desktop.
This script preps obsidian notes for Hugo usage
# ______ __ _
# / ____/_ ______ _____/ /_(_)___ ____ _____
# / /_ / / / / __ \/ ___/ __/ / __ \/ __ \/ ___/
# / __/ / /_/ / / / / /__/ /_/ / /_/ / / / (__ )
# /_/ \__,_/_/ /_/\___/\__/_/\____/_/ /_/____/
function Get-YamlFrontMatter
{
param
(
[string]$FilePath
)
# Tags to Strip
$TagsToStrip = "T1","T2","T3"
# Read the content of the file
$global:content = Get-Content -Path $FilePath -Raw
if ([string]::IsNullOrEmpty($global:content))
{
return $null
}
# Define the regex pattern for matching YAML front matter
$pattern = '(?sm)^---\r?\n(.*?)\r?\n---'
# Extract YAML front matter using regex
$frontmatterMatch = [regex]::Match($content, $pattern)
if (-not $frontmatterMatch.Success)
{
Write-warning "No YAML front matter found in the file: $FilePath"
return $null
}
# Get the matched front matter content
$frontmatterContent = $frontmatterMatch.Groups[1].Value
# Convert YAML front matter string to PowerShell object and remove unwanted tags
try
{
$yamlObject = $frontmatterContent | ConvertFrom-Yaml
# remove our unwanted tags
if ($TagsToStrip)
{
foreach ($tag in $TagsToStrip)
{
$null = $yamlObject.tags.remove($tag)
}
}
# handle obsidian child tags
$yamlObject.tags = $yamlObject.tags -split "/"
return $yamlObject
}
catch
{
Write-Warning "Failed to convert YAML front matter to PowerShell object. Error: $_"
return $null
}
}
function Test-HashtableKeys
{
param
(
[hashtable]$Hashtable,
[string[]]$KeysToCheck
)
# Check if all keys exist in the hashtable
$missingKeys = $KeysToCheck | Where-Object { -not $Hashtable.ContainsKey($_) }
if ($missingKeys.Count -eq 0)
{
return $true
} else
{
Write-host "Not all keys exist in the hashtable. Missing keys: $($missingKeys -join ', ')"
return $false
}
}
function Convert-WikiLinksToMdLinks
{
param (
[string]$Content
)
# Define the regex pattern for matching wiki links
$pattern = '\!\[\[(.*?)\]\]'
# Find all matches of the wiki link pattern
$matches = $Content | Select-String -Pattern $pattern -AllMatches | ForEach-Object { $_.Matches }
# Replace wiki links with Markdown links
foreach ($match in $matches) {
$linkText = $match.Groups[1].Value
# Check if the link contains a size specification after '|'
$sizeMatch = $linkText -split '\|' | Select-Object -Skip 1
if ($sizeMatch) {
$size = $sizeMatch.Trim()
$linkText = $linkText -split '\|' | Select-Object -First 1
} else {
$size = ''
}
$linkText = $linkText -replace '\s', '-'
$markdownLink = "{{< figure src=`"../$linkText`" width=`"$size`">}}"
$Content = $Content -replace [regex]::Escape($match.Value), $markdownLink
}
return $Content
}
# ______ _____
# / ____/___ ____ / __(_)___ _
# / / / __ \/ __ \/ /_/ / __ `/
# / /___/ /_/ / / / / __/ / /_/ /
# \____/\____/_/ /_/_/ /_/\__, /
# /____/
$BaseUrl = "blog.wizardsofthe.cloud/posts/"
# the keys we want to be in our markdown before we can send them to Hugo
$KeysToVerify = @("title", "date", "type", "published")
# Set the path to the folder containing the Markdown files
$folderPath = "V:\Obsidian Vaults\Main Vault"
$ObsidianAssetsPath = "V:\Obsidian Vaults\Main Vault\Assets"
# Set the destination directory for matching Markdown files
$PostsDirectory = "V:\Repositories\WizardsOfTheCloud\Blog\WizardsOfTheCloudWorkBench\content\posts"
$ProjectsDirectory = "V:\Repositories\WizardsOfTheCloud\Blog\WizardsOfTheCloudWorkBench\content\projects"
$ClearExistingPosts = $true
# _____ __ __
# / ___// /_____ ______/ /_
# \__ \/ __/ __ `/ ___/ __/
# ___/ / /_/ /_/ / / / /_
# /____/\__/\__,_/_/ \__/
# Get all Markdown files in the folder
$markdownFiles = Get-ChildItem -Path $folderPath -Filter "*.md" -File
if ($ClearExistingPosts -eq $true)
{
Get-ChildItem -Path $PostsDirectory -Recurse | remove-item -Force -Confirm:$false -Recurse
Get-ChildItem -Path $ProjectsDirectory -Recurse | remove-item -Force -Confirm:$false -Recurse
}
# Iterate through each Markdown file
foreach ($file in $markdownFiles)
{
$FrontMatter = Get-YamlFrontMatter -FilePath $file.FullName
if (-not($null=[string]::IsNullOrEmpty($FrontMatter)))
{
# Check if the content contains "PublishToBlog: true"
if (Test-HashtableKeys -Hashtable $frontmatter -KeysToCheck $KeysToVerify)
{
Write-host "File $($file.Name) contains the needed keys to be processed"
# check if our file can be published to hugo
if ($frontmatter.published -eq $true)
{
switch ($frontmatter.type)
{
"post"
{
# Copy the matching Markdown file to the destination directory
$PostLocation = "$PostsDirectory" + "\" + $($FrontMatter.title).Replace(' ','-')
$PostLocationFullName = $PostLocation + "\" + $($FrontMatter.title).Replace(' ','-') + $($file.Extension)
}
"page"
{
# Copy the matching Markdown file to the destination directory
$PostLocation = "$ProjectsDirectory" + "\" + $($FrontMatter.title).Replace(' ','-')
$PostLocationFullName = $PostLocation + "\" + $($FrontMatter.title).Replace(' ','-') + $($file.Extension)
}
Default {}
}
new-item -Path $PostLocation -ItemType Directory
# Find and copy linked non-Markdown files to the assets directory
$MatchesFound = [regex]::Matches($global:content , '\[\[(.*?)\]\]')
foreach ($match in $MatchesFound)
{
$linkedFile = $match.Groups[1].Value
if (-not ($linkedFile -like "*.md*"))
{
<#
Create a new filepath for our attachment, we'll need to remove spaces from the filename and replace them with "-"
hugo does not like spaces in filenames
#>
if ($linkedFile -like "*|*")
{
Write-Host "Linked file has a pipe in it for resizing"
# we take the second entry from our split [1], this contains the size. The first one [0] is the filename
$linkedFile = $linkedFile.Split("|")[0]
}
$linkedFilePath = Join-Path -Path $ObsidianAssetsPath -ChildPath $linkedFile
if (Test-Path -Path $linkedFilePath -PathType Leaf -ErrorAction Ignore)
{
Write-Host "Copying linked file '$linkedFile' to $PostLocation"
Copy-Item -Path $linkedFilePath -Destination "$PostLocation\$($linkedFile.Replace(' ','-'))" -Force
}
else
{
write-warning "$linkedFilePath was not found"
}
}
elseif ($linkedFile -like "*.md*")
{
if ($linkedFile -like "*|*")
{
Write-Host "Linked note as an alias"
# we take the second entry from our split [1], this contains the alias. The first one [0] is the filename
$alias = ($linkedFile.Split("|")[1]).trim()
# replace spaces with dashes to form our correct link to the note.
$linkname = $alias.Replace(' ','-')
$link = "$BaseUrl" + "$linkname" + "/" + "$linkname"
}
}
}
# Now that our files are moved we need to convert the wiki links to mdlinks and save our content in the hugo folder
$UpdatedContent = convert-WikiLinksToMdLinks -Content $Global:content
$UpdatedContent| Out-File -FilePath $PostLocationFullName -Force
}
}
else
{
write-host "skipped $($file.name) (properties check)"
}
}
else
{
Write-Host "skipped $($file.name) (no frontmatter)"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment