前々回の記事(以下)に記載の「select_music.js」の生成方法にVisual Studioに付属しているテキストジェネレータT4(Text Template Transformation Toolkit)を使ってみます。
Google Homeを使って、NASに設置したmp3を再生するシステム(06)~slackとhubotの設定 – リトルラボ (littlelab.jp)
目標設定
CSVで設定値を入力して、その入力値をt4で読み込んで、読込んだ結果に基づいてソースコードを生成出来れば便利に使用できるのではないかという想定で試してみます。
実行環境:Windows10
筆者の練習のために技巧的な探求を行なっていますので、不要な方は適宜読み飛ばしてください。
t4の実行ファイルのパス
まず、Visual Studioに付属している実行ファイルを探します。筆者の場合は、Visual Studio Communityを使用しており、実行ファイルは以下のパスにありました。
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\TextTransform.exe
https://www.atmarkit.co.jp/ait/articles/0608/18/news105.html
t4によってファイルを生成するコマンド
今回は、入力ファイル”select_music.tt”に記載されたt4のソースコードから出力ファイル”select_music.js”を生成します。この場合は、TextTransform.exeのパスを設定して、以下のコマンドを実行します。
TextTransform select_music.tt -o select_music.js
t4入力ファイルを作成
実際に、t4入力ファイル”select_music.tt”を作成していきます。
t4入力ファイルに、アセンブリ参照でMicrosoft.VisualBasicを指定すると、名前空間Microsoft.VisualBasic.FileIOにあるTextFieldParserクラスが使えるようになります。select_music.ttの冒頭に以下の行を追加すると、アセンブリ参照でMicrosoft.VisualBasicを指定できます。
<#@ assembly name="Microsoft.VisualBasic" #>
これを踏まえて、select_music.ttを以下のように記述します。
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="Microsoft.VisualBasic" #>
<#@ import namespace="Microsoft.VisualBasic.FileIO" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".js" #>
<#
List<string[]> readResults = new List<string[]>();
using var parser = new TextFieldParser("./music_source.csv", Encoding.GetEncoding("SHIFT-JIS"));
parser.TextFieldType = FieldType.Delimited;
parser.Delimiters = new[] { "," };
parser.HasFieldsEnclosedInQuotes = true;
parser.TrimWhiteSpace = true;
while (parser.EndOfData == false)
{
string[] fields = parser.ReadFields();
readResults.Add(fields);
foreach(var f in fields) Console.WriteLine(f);
}
parser.Close();
#>
const musicData = [
<#
foreach(var line in readResults){
#>
{
filename: '<#= line[0] #>',
comment:'<#= line[1] #>',
keys:[
'<#= line[0].Replace(".mp3","") #>',
<#
for(int i=2; i<line.Length; i++){
if(line[i]=="") continue;
#>
'<#= line[i] #>',
<#
}
#>
]
},
<#
}
#>
];
function selectMusicFile(str){
for(i=0; i < musicData.length; i++){
if(musicData[i].filename == str || musicData[i].comment == str) return musicData[i];
var keys = musicData[i].keys;
for(j=0;j<keys.length; j++){
if(str == keys[j]){
return musicData[i];
}
}
}
return {
filename:null,
comment:null,
};
}
入力用のcsvファイルは、selet_music.ttを同じ階層で以下の内容としました。
エクセル上での表示
テキストでの表示
example01.mp3,再生前にしゃべります01,keyword01-01,keyword01-02,keyword01-03,keyword01-04,keyword01-05
example02.mp3,再生前にしゃべります02,keyword02-01,keyword02-02,keyword02-03,keyword02-04,keyword02-05
example03.mp3,再生前にしゃべります03,keyword03-01,keyword03-02,keyword03-03,,
example04.mp3,再生前にしゃべります04,keyword04-01,keyword04-02,keyword04-03,keyword04-04,
example05.mp3,再生前にしゃべります05,keyword05-01,keyword05-02,keyword05-03,keyword05-04,keyword05-05
TextTransform.exeのパスを設定して、以下のコマンドを実行します。
TextTransform select_music.tt -o select_music.js
その結果、以下のような内容のselect_music.jsが生成されます。
const musicData = [
{
filename: 'example01.mp3',
comment:'再生前にしゃべります01',
keys:[
'example01',
'keyword01-01',
'keyword01-02',
'keyword01-03',
'keyword01-04',
'keyword01-05',
]
},
{
filename: 'example02.mp3',
comment:'再生前にしゃべります02',
keys:[
'example02',
'keyword02-01',
'keyword02-02',
'keyword02-03',
'keyword02-04',
'keyword02-05',
]
},
{
filename: 'example03.mp3',
comment:'再生前にしゃべります03',
keys:[
'example03',
'keyword03-01',
'keyword03-02',
'keyword03-03',
]
},
{
filename: 'example04.mp3',
comment:'再生前にしゃべります04',
keys:[
'example04',
'keyword04-01',
'keyword04-02',
'keyword04-03',
'keyword04-04',
]
},
{
filename: 'example05.mp3',
comment:'再生前にしゃべります05',
keys:[
'example05',
'keyword05-01',
'keyword05-02',
'keyword05-03',
'keyword05-04',
'keyword05-05',
]
},
];
function selectMusicFile(str){
for(i=0; i < musicData.length; i++){
if(musicData[i].filename == str || musicData[i].comment == str) return musicData[i];
var keys = musicData[i].keys;
for(j=0;j<keys.length; j++){
if(str == keys[j]){
return musicData[i];
}
}
}
return {
filename:null,
comment:null,
};
}
exports.selectMusicFile = selectMusicFile;