その改行する目安なわけですが、コンソールには何桁目で必ず改行するという限界値が決められているので、それを各ユーザーから取得すれば行数は計算できると思います。
勿論、出力する値はこちらにあるわけなので、
floor(出力文字数(出力バイト数(幅))/行最大文字数)
で計算するといいのかなぁと考えました。
そして、肝心の行最大文字数の取得方法なんですが、これはNode.jsからの方法は分からなかったです。
代替案ですが、Node.jsは一応、コマンドプロンプトとかターミナルをchild_process.exec/execSyncから呼べますので、各環境に合わせてコマンドを叩けば取得できるのではないかと思います。
当方はWindows環境なので、Linux/Unixは分かりませんけど、Windowsではなんとか取得できたので、ソースを載せておきます。
色々弄って遊んでいたら少々プログラムが大きくなってしまいましたが、そこは目をつぶってください。
js
1const readline=require("readline");
2const exec=require("child_process").execSync;
3const rl=readline.createInterface(process.stdin,process.stdout);
4
5class Progress{
6 constructor(width,parMax){
7 //最大の列数
8 this.columns=exec("mode") //コマンドプロンプトからmodeを呼び出して、
9 .toString() //文字列として取得して、
10 .split(/\r\n/) //改行で分割し、
11 .filter(val=>{ //文字化けした" 桁数: "(=" ����: ")を検索して、
12 if(val.replace(" ����: ","")!=val) return val;
13 })[0].replace(" ����: ","")|0 //無駄な文字を消して整数に変換。
14
15 //進捗度
16 this.par=0;
17 //目標進捗度
18 this.parMax=parMax;
19 //プログレスバーの長さ
20 this.width=width;
21 }
22
23 //プログレスバーの更新
24 view(message){
25 const parcent=this.par/this.parMax;
26 const widthNow=Math.floor(this.width*parcent);
27
28 const gauge=(">".repeat(widthNow)+" ".repeat(this.width-widthNow));
29 const output=`#[${gauge}]#(${(parcent*100).toFixed(1)}%<-${this.par}/${this.parMax})`;
30
31 //列数と文字数(半角のみ)から実際の行数を計算
32 const rows=Math.floor(message.length/this.columns)+2;
33 console.log(output);
34
35 //現在位置より下を消去する
36 readline.clearScreenDown(process.stdout);
37
38 console.log(message);
39
40 //行数分上に移動。
41 readline.moveCursor(process.stdout,0,-rows);
42
43 this.par++;
44 }
45
46 //プログレスバーの完了
47 done(lastMessage){
48 //lastMessageの左を埋める文字数
49 const sideLen=Math.floor((this.width-lastMessage.length)/2);
50
51 var gauge="=".repeat(sideLen)+lastMessage
52 gauge+="=".repeat(this.width-gauge.length)
53 const output=`#[${gauge}]#(100%<-${this.parMax}/${this.parMax})`;
54
55 //最大列数に合うように空白埋めして表示
56 process.stdout.write(output+" ".repeat(this.columns-output.length)+"\r");
57
58 //現在位置より下を消去する
59 readline.clearScreenDown(process.stdout);
60 }
61}
62
63const g=(function*(){
64 const firstMsg="FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep FirstStep";
65 const secondMsg="SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep SecondStep";
66 const thirdMsg="ThirdStep ThirdStep ThirdStep ThirdStep";
67 console.log("START!");
68
69 const width=55;
70 const works=270;
71 const prg=new Progress(width,works);
72
73 for(let i=0;i<=works;i++){
74 yield setTimeout(()=>g.next(),90);
75 if(i<40){
76 prg.view(firstMsg);
77 }
78 else if(i<90){
79 prg.view(secondMsg);
80 }
81 else{
82 prg.view(thirdMsg);
83 }
84 }
85 prg.done(">> Done! <<");
86 console.log("終了しました!");
87 rl.once("line",process.exit);
88})();
89g.next();
追記:
js
1> process.stdout
2WriteStream {
3 ...,
4 columns: 80,
5 rows: 25,
6 ...,
7 destroy: [Function] }
8
9> process.stdout.columns
1080
process.stdoutを叩いてみたらその中にcolumns入ってました。
これで置換すればどのプラットフォームでも桁数を取得できるのではないでしょうか。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/02/09 06:16 編集