public/Get-WpcRelativeSourcePath.ps1

function Get-WpcRelativeSourcePath {
    param(
        [Parameter(Mandatory = $true)]
        [string] $SourceDir,
        [Parameter(Mandatory = $true)]
        [string] $SourceFilePath
    )

    $resolvedSourceDir = (Resolve-Path $SourceDir).Path
    $resolvedSourceFilePath = (Resolve-Path $SourceFilePath).Path

    if (-not $resolvedSourceFilePath.StartsWith($resolvedSourceDir, [System.StringComparison]::OrdinalIgnoreCase)) {
        throw "Source file '$resolvedSourceFilePath' is not under source directory '$resolvedSourceDir'."
    }

    return [IO.Path]::GetRelativePath($resolvedSourceDir, $resolvedSourceFilePath).Replace('\', '/')
}