Themes.ps1

<#
    .SYNOPSIS
        Convert a Office 365 UI Fabric theme to the Valo format
    .DESCRIPTION
        This Cmdlet is used to conver an Office 365 UI Fabric theme to the
        usable format by Valo (which is a .txt)
 
        JSON, PS1 file extensions are supported.
    .LINK
        Nexus Innovations : http://www.nexusinno.com
#>

function global:ConvertTo-ValoTheme {
    [CmdletBinding()]
    Param(
        [ValidateScript({Test-Path $_})]
        [Parameter(Mandatory=$true)]
        [string]$InputFilePath,

        [ValidateScript({Test-Path $_})]
        [Parameter(Mandatory=$false)]
        [string]$OutputPath
    )

    $file = Get-ChildItem $InputFilePath

    switch($file.Extension) {
        ".json" {
            Write-Verbose "Converting JSON theme to Valo Theme"
            $converted = $file | Convert-JsonTheme
        }
        ".ps1" {
            Write-Verbose "Converting PowerShell theme to Valo Theme"
            $converted = $file | Convert-PowerShellTheme
        }
        default {
            throw "Unsupported Theme file extension!"
        }
    }

    # Adding Valo theme properties with default values
    $converted += @("primaryBackground = #ffffff", "primaryText = #333333",
                    "disabledBackground = #ffffff", "disabledText = #333333")

    Write-Verbose "Writing theme data to txt file"
    $valoTheme = Join-Path -Path $file.Directory.FullName -ChildPath "$($file.BaseName).txt"
    if(![string]::IsNullOrEmpty($OutputPath)) {
        $valoTheme = Join-Path -Path $OutputPath -ChildPath "$($file.BaseName).txt"
    }
    
    Set-Content -Path $valoTheme -Value $converted
}

function global:ConvertFrom-ValoTheme {
    Param(
        [Parameter(Mandatory=$true)]
        [ValidateScript({Test-Path $_})]
        [string]$ValoThemePath,

        [ValidateScript({Test-Path $_})]
        [string]$OutputPath = (Get-Location)
    )

    Write-Verbose "[ConvertFrom-ValoTheme] Entering function scope"
    $valoThemeEntries = Get-Content $ValoThemePath

    Write-Verbose "[ConvertFrom-ValoTheme] Converting text based entries to PowerShell hastable"
    $dictionary = @{}
    $valoThemeEntries | ForEach-Object {
        $entry = $_.Split("=").Trim()
        $dictionary.Add($entry[0], $entry[1])
    }

    Write-Verbose "[ConvertFrom-ValoTheme] Converting Hashtable to json"
    $converted = $dictionary | ConvertTo-Json

    $themeFileName = $ValoThemePath | Expand-FileNameFromPath
    $destination = Join-Path $OutputPath "$themeFileName.json"

    Write-Verbose "[ConvertFrom-ValoTheme] Persisting converted file to $destination"
    Set-Content -Path $destination -Value $converted
}

function script:Convert-JsonTheme {
    Param(
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [System.IO.FileInfo]$Theme
    )

    $convertedContent = @()
    $json = Get-Content $Theme.FullName | Out-String | ConvertFrom-Json
    
    $themeColorNames = $json | `
        Get-Member -MemberType NoteProperty | `
        Select-Object -ExpandProperty Name

    foreach($name in $themeColorNames) {
        $content = [string]::Format("{0} = {1}",$name, $json."$name")
        $convertedContent += $content
    }
    
    return $convertedContent
}

function script:Convert-PowerShellTheme {
    Param(
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [System.IO.FileInfo]$Theme
    )

    # Source PowerShell file to access the Hashtable within
    $dictionary = . $theme.FullName

    $convertedContent = @()
    foreach($key in $dictionary.Keys) {
        $content = [string]::Format("{0} = {1}", $key, $dictionary[$key])
        $convertedContent += $content
    }

    return $convertedContent
}

function script:Expand-FileNameFromPath {
    Param (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [string]$ValoThemePath
    )

    # Extract the theme file name without the extension
    return (Split-Path $ValoThemePath -Leaf).Split(".") | Select-Object -First 1
}