public/New-TriliumNote.ps1
function New-TriliumNote { <# .SYNOPSIS Creates a new Trilium note. .DESCRIPTION Creates a new Trilium note under the specified parent note ID (defaults to 'root') with the provided content. You must provide content for the note. Optionally, you can specify a title and note type. If -NoteType is not specified, the note will default to type 'text' and mime 'text/html'. .PARAMETER ParentNoteId The parent note ID to create the new note under. If not specified, the note will be created under the root note. Default is 'root'. Required? false Position? 0 Default value 'root' Accept pipeline input? false Accept wildcard characters? false .PARAMETER Title The title of the new note. Optional. If not specified, the note will be created without a title. Required? false Position? 1 Default value None Accept pipeline input? false Accept wildcard characters? false .PARAMETER Content The content of the new note. This parameter is required. The note will not be created without content. Required? true Position? 2 Default value None Accept pipeline input? false Accept wildcard characters? false .PARAMETER NoteType The type of the new note. Optional. Must be one of: text, book, canvas, mermaid, geoMap, mindMap, relationMap, renderNote, webview, PlainText, CSS, html, http, JSbackend, JSfrontend, json, markdown, powershell, python, ruby, shellBash, sql, sqliteTrilium, xml, yaml If not specified, defaults to 'text' with mime 'text/html'. Required? false Position? Named Default value None Accept pipeline input? false Accept wildcard characters? false .PARAMETER SkipCertCheck Option to skip certificate check. Optional. Use this if you are connecting to a Trilium server with a self-signed certificate. Required? false Position? Named Default value None Accept pipeline input? false Accept wildcard characters? false .PARAMETER Markdown Option to convert markdown content to HTML. Optional. Use this if you want to convert the content from markdown to HTML before creating the note. Only applicable if -NoteType is 'text'. If -Markdown is specified, -NoteType must be 'text'. Required? false Position? Named Default value None Accept pipeline input? false Accept wildcard characters? false .PARAMETER NoMath Option to disable math extension for markdown content. Optional. By default, math extension is enabled for inline and block LaTeX math rendering. Only applicable if -Markdown and -NoteType is 'text'. Required? false Position? Named Default value None Accept pipeline input? false Accept wildcard characters? false .EXAMPLE New-TriliumNote -Content "This is a new note." Creates a new note under the root with the specified content and default type 'text' and mime 'text/html'. .EXAMPLE New-TriliumNote -Title "My Note" -Content "This is a new note." -NoteType markdown Creates a new note under the root with the specified title, content, and type 'code' with mime 'text/x-markdown'. .EXAMPLE New-TriliumNote -ParentNoteId "abcdef123456" -Title "Child Note" -Content "Child note content." Creates a new note under the specified parent note with the given title and content, using default type 'text' and mime 'text/html'. .EXAMPLE New-TriliumNote -Content "Geo data" -NoteType geoMap Creates a new note under the root with the specified content and type 'geoMap' with mime 'application/json'. .NOTES This function requires that authentication has been set using Connect-TriliumAuth. The -Content parameter is always required. All other parameters are optional. If -NoteType is not specified, the note will be created as a standard text note (type 'text', mime 'text/html'). If -ParentNoteId is not specified, the note will be created under the root note. If -Title is not specified, the note will be created without a title. .LINK https://github.com/ptmorris1/TriliumNext-Powershell-Module #> [CmdletBinding(SupportsShouldProcess = $true)] param ( # Parent note ID to create the new note under [Parameter()] [string]$ParentNoteId = 'root', # Title of the new note [Parameter()] [string]$Title, # Content of the new note [Parameter(Mandatory = $true)] [string]$Content, # Optional note type [Parameter()] [ValidateSet('file','text','book','canvas','mermaid','geoMap','mindMap','relationMap','renderNote','webview', 'PlainText','CSS','html','http','JSbackend','JSfrontend','json','markdown','powershell','python','ruby','shellBash','sql','sqliteTrilium','xml','yaml')] [string]$NoteType, [Parameter()] [switch]$SkipCertCheck, [Parameter()] [switch]$Markdown, [Parameter()] [switch]$NoMath ) begin { if (!$global:TriliumCreds) { Write-Error -Message 'Need to run: Connect-TriliumAuth'; exit } if ($Markdown) { if ($NoteType -and $NoteType -ne 'text') { Write-Error -Message 'If -Markdown is specified, -NoteType must be "text".' exit } $NoteType = 'text' $moduleRoot = $MyInvocation.MyCommand.Module.ModuleBase $dllPath = Join-Path -Path $moduleRoot -ChildPath 'lib\Markdig.dll' if (-not ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.Location -eq (Resolve-Path $dllPath) })) { Add-Type -Path $dllPath } $builder = [Markdig.MarkdownPipelineBuilder]::new() [Markdig.MarkdownExtensions]::UseAdvancedExtensions($builder) | Out-Null if (-not $NoMath) { # Enable the math extension (inline and block LaTeX) [Markdig.MarkdownExtensions]::UseMathematics($builder) | Out-Null } $pipeline = $builder.Build() $Content = [Markdig.Markdown]::ToHtml($Content, $pipeline) if (-not $NoMath) { $Content = $Content.Replace('<span class="math"','<span class="math-tex"') $Content = $Content.Replace('<div class="math"','<span class="math-tex"') } # Patch code block classes to MIME-style if needed # ~50 common languages and their MIME-style class equivalents $LanguageToMimeMap = @{ "powershell" = "application-x-powershell" "bash" = "application-x-sh" "shell" = "application-x-sh" "zsh" = "application-x-zsh" "sh" = "application-x-sh" "python" = "text-x-python" "javascript" = "application-x-javascript" "typescript" = "application-x-typescript" "java" = "text-x-java-source" "csharp" = "text-x-csharp" "cs" = "text-x-csharp" "cpp" = "text-x-c++src" "c" = "text-x-csrc" "go" = "text-x-go" "rust" = "text-x-rustsrc" "ruby" = "application-x-ruby" "perl" = "application-x-perl" "php" = "application-x-php" "html" = "text-html" "xml" = "application-xml" "json" = "application-json" "yaml" = "application-x-yaml" "toml" = "application-toml" "markdown" = "text-x-markdown" "sql" = "application-sql" "dockerfile" = "text-x-dockerfile" "makefile" = "text-x-makefile" "ini" = "text-x-ini" "config" = "text-x-config" "kotlin" = "text-x-kotlin" "swift" = "application-x-swift" "r" = "text-x-r" "scala" = "text-x-scala" "groovy" = "application-x-groovy" "vbnet" = "text-x-vbnet" "dart" = "application-x-dart" "haskell" = "text-x-haskell" "elixir" = "application-x-elixir" "clojure" = "application-x-clojure" "lua" = "text-x-lua" "matlab" = "application-x-matlab" "fortran" = "text-x-fortran" "assembly" = "text-x-asm" "asm" = "text-x-asm" "latex" = "application-x-latex" "plaintext" = "text-plain" "text" = "text-plain" } # Replace all class="language-xxx" with correct MIME-style $Content = $Content -replace 'class="language-([a-z0-9+\-]+)"', { param($match) $lang = $matches[1] if ($LanguageToMimeMap.ContainsKey($lang)) { $mime = $LanguageToMimeMap[$lang] } else { if ($lang -match '^(html|xml|json|markdown|sql|text|plaintext)$') { $mime = "text-$lang" } elseif ($lang -match '^(c|cpp|csharp|java|go|sh|bash|powershell)$') { $mime = "text-x-$lang" } else { $mime = "application-x-$lang" } } 'class="language-' + $mime + '"' } } } process { try { if ($SkipCertCheck -eq $true) { $PSDefaultParameterValues = @{'Invoke-RestMethod:SkipCertificateCheck' = $true } } $TriliumHeaders = @{} $TriliumHeaders.Add('Authorization', "$($TriliumCreds.Authorization)") $uri = "$($TriliumCreds.URL)/create-note" $mimeMap = @( [PSCustomObject]@{ Note = 'PlainText'; Type = 'code'; Mime = 'text/plain' } [PSCustomObject]@{ Note = 'CSS'; Type = 'code'; Mime = 'text/css' } [PSCustomObject]@{ Note = 'html'; Type = 'code'; Mime = 'text/html' } [PSCustomObject]@{ Note = 'http'; Type = 'code'; Mime = 'message/http' } [PSCustomObject]@{ Note = 'JSbackend'; Type = 'code'; Mime = 'application/javascript;env=backend' } [PSCustomObject]@{ Note = 'JSfrontend'; Type = 'code'; Mime = 'application/javascript;env=frontend' } [PSCustomObject]@{ Note = 'json'; Type = 'code'; Mime = 'application/json' } [PSCustomObject]@{ Note = 'markdown'; Type = 'code'; Mime = 'text/x-markdown' } [PSCustomObject]@{ Note = 'powershell'; Type = 'code'; Mime = 'application/x-powershell' } [PSCustomObject]@{ Note = 'python'; Type = 'code'; Mime = 'text/x-python' } [PSCustomObject]@{ Note = 'ruby'; Type = 'code'; Mime = 'text/x-ruby' } [PSCustomObject]@{ Note = 'shellBash'; Type = 'code'; Mime = 'text/x-sh' } [PSCustomObject]@{ Note = 'sql'; Type = 'code'; Mime = 'text/x-sql' } [PSCustomObject]@{ Note = 'sqliteTrilium'; Type = 'code'; Mime = 'text/x-sqlite;schema=trilium' } [PSCustomObject]@{ Note = 'xml'; Type = 'code'; Mime = 'text/xml' } [PSCustomObject]@{ Note = 'yaml'; Type = 'code'; Mime = 'text/x-yaml' } [PSCustomObject]@{ Note = 'text'; Type = 'text'; Mime = 'text/html' } [PSCustomObject]@{ Note = 'book'; Type = 'book'; Mime = $null } [PSCustomObject]@{ Note = 'canvas'; Type = 'canvas'; Mime = 'application/json' } [PSCustomObject]@{ Note = 'mermaid'; Type = 'mermaid'; Mime = 'text/mermaid' } [PSCustomObject]@{ Note = 'geoMap'; Type = 'geoMap'; Mime = 'application/json' } [PSCustomObject]@{ Note = 'mindMap'; Type = 'mindMap'; Mime = 'application/json' } [PSCustomObject]@{ Note = 'relationMap'; Type = 'relationMap'; Mime = 'application/json' } [PSCustomObject]@{ Note = 'renderNote'; Type = 'renderNote'; Mime = $null } [PSCustomObject]@{ Note = 'webview'; Type = 'webview'; Mime = $null } ) $body = @{ parentNoteId = $ParentNoteId } if ($Title) { $body.title = $Title } if ($Content) { $body.content = $Content } if ($NoteType) { $mimeObj = $mimeMap | Where-Object { $_.Note -eq $NoteType } if ($mimeObj) { $body.type = $mimeObj.Type if ($null -ne $mimeObj.Mime) { $body.mime = $mimeObj.Mime } } else { $body.type = $NoteType } } elseif (-not $body.ContainsKey('type')) { $body.type = 'text' $body.mime = 'text/html' } $body = $body | ConvertTo-Json if ($PSCmdlet.ShouldProcess($uri, 'Create new note')) { Invoke-RestMethod -Uri $uri -Headers $TriliumHeaders -SkipHeaderValidation -ContentType 'application/json' -Body $body -Method Post } } catch { $_.Exception.Response } } end { return } } |