2017年12月16日

【PowerShell】コピーしたソースコードに含まれる0xC2A0(no-break space)を半角スペース(0x20)に変換するスクリプトを作ってみた


当ブログの記事中に掲載しているソースコードをコピーしてVBEなどのエディターに貼り付けると、行頭の空白が変な文字に変換されててそのままでは使えないことがあります。

たとえば、このようなソースコードをコピーして、
Public Sub MakeForm()

    CreateForm
    
    DoCmd.Restore
    
End Sub

AccessのVBEに貼り付けてみると、

頭に「?」が並んだ状態になってしまいます。

これでは当然コンパイルできませんし、実行も出来ません。

調べてみると、どうやらこれはno-break spaceというものでWeb上で複数の空白を表現するのに使われたりするらしいんです。そしてUTF-8だと0xC2A0のコードになるようなんです。

あと気になるのは、この現象が起きるのはChromeだけなんですよね。
FirefoxやEdgeだと起きません。

なんなんですかね。

Javascriptの解釈の仕方が違うんですかね。

まあでも、このブログのアクセスの6割ぐらいがChromeからで無視するわけにはいかないんで、この0xC2A0を0x20に変換するスクリプトを作ってみました。

################################################################################
# Convert-C2A0.ps1
# 
# 0xC2A0を0x20に変換する
#
################################################################################

#コードを変換
function ConvertStr{
    param($code)

    [Byte[]]$data = [System.Text.Encoding]::UTF8.GetBytes($code)

    [byte[]]$b = @()

    [bool]$flag = $false

    for ($i=0; $i -lt $data.Count; $i++)
    {
        if ($data[$i].ToString("X2") -eq "C2")
        {
            $preIndex = $i
            $flag = $true
        }
        elseif (($flag -eq $true) -and ($data[$i].ToString("X2") -eq "A0"))
        {
            $b += 0x20
            $flag = $false
        }
        elseif (($flag -eq $true) -and ($data[$i].ToString("X2") -ne "A0"))
        {
            $b += $data[$preIndex]
            $b += $data[$i]
            $flag = $false
        }
        else
        {
            $b += $data[$i]
        }
    }

    $str = [System.Text.Encoding]::UTF8.GetString($b)

    return($str)
}


Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

#フォーム
$form = New-Object System.Windows.Forms.Form 
$form.Text = "Convert C2A0"
$form.Size = New-Object System.Drawing.Size(400,240) 
$form.StartPosition = "CenterScreen"

#ラベル
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(20,15) 
$label.Size = New-Object System.Drawing.Size(250,20) 
$label.Text = "コードを貼り付けて変換ボタンを押してください。"
$form.Controls.Add($label) 

#テキストボックス
$textBox = New-Object System.Windows.Forms.TextBox 
$textBox.Location = New-Object System.Drawing.Point(20,40) 
$textBox.Multiline = $True
$textBox.AcceptsReturn = $True
$textBox.AcceptsTab = $True
$textBox.WordWrap = $True
$textBox.ScrollBars = [System.Windows.Forms.ScrollBars]::Vertical
$textBox.Anchor = (([System.Windows.Forms.AnchorStyles]::Left) `
              -bor ([System.Windows.Forms.AnchorStyles]::Top) `
              -bor ([System.Windows.Forms.AnchorStyles]::Right) `
              -bor ([System.Windows.Forms.AnchorStyles]::Bottom))
$textBox.Size = New-Object System.Drawing.Size(340,110) 
$textBox.Add_KeyDown({if ($_.Control -and ($_.KeyCode -eq [System.windows.forms.Keys]::A)) 
    {$textBox.SelectAll()}})
$form.Controls.Add($textBox) 

#変換ボタン
$ConvertButton = New-Object System.Windows.Forms.Button
$ConvertButton.Location = New-Object System.Drawing.Point(270,10)
$ConvertButton.Size = New-Object System.Drawing.Size(75,23)
$ConvertButton.Text = "変換"
$ConvertButton.Anchor = (([System.Windows.Forms.AnchorStyles]::Left) `
                    -bor ([System.Windows.Forms.AnchorStyles]::Top))
$ConvertButton.Add_Click({$textBox.Text=ConvertStr $textBox.Text; `
                          [System.Windows.Forms.MessageBox]::Show("変換が完了しました。")})
$form.Controls.Add($ConvertButton)

#閉じるボタン
$ExitButton = New-Object System.Windows.Forms.Button
$ExitButton.Location = New-Object System.Drawing.Point(285,160)
$ExitButton.Size = New-Object System.Drawing.Size(75,23)
$ExitButton.Text = "閉じる"
$ExitButton.Anchor = (([System.Windows.Forms.AnchorStyles]::Right) `
                   -bor ([System.Windows.Forms.AnchorStyles]::Bottom))
$ExitButton.Add_Click({$form.Close()})
$form.Controls.Add($ExitButton)

#フォームを常に手前に表示
$form.Topmost = $True

#フォームをアクティブにし、テキストボックスにフォーカスを設定
$form.Add_Shown({$textBox.Select()})

#フォームを表示
$result = $form.ShowDialog()
少し解説すると、テキストボックスに貼り付けられた文字列を、まずUTF-8としてバイト型配列に変換します。次に、バイト型配列を1バイトずつチェックしていき、"0xC2" "0xA0"と並んで来た場合に"0x20"に置き換えるようにしています。あとは、返還後の文字列をテキストボックスに書き込んでいます。

使用法

まず、上記スクリプトを名前を付けてファイルに保存し、PowerShellのプロンプトで実行してください。


スクリプトを実行すると、このような画面が表示されます。



画面が表示されたらテキストボックスにソースコードを貼り付け、[変換]ボタンをクリックします。



変換が終わるとこのようなメッセージが表示されます。

変換後の文字列が同じテキストボックスに表示されますので、このテキストボックスのソースコードをコピーして使ってください。







スポンサーリンク