質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

323閲覧

文ごとにハイライトが出来ない

syen2501

総合スコア38

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

1クリップ

投稿2019/04/09 03:59

文ごとにハイライトを行うプログラムを書いているのですが、
どうしても、最初の文だけがハイライトで表示され、しかも間違った部分をハイライトしてしまいます。
原因が分からないので、少しでも教えて頂けると幸いです。
※JSONファイルの「=>」の右側を取得し、ハイライトするプログラムを下記に記載しています。
dependencyRelationListとCountは今回は使っていませんので、空が入ります。

<実行結果>
イメージ説明
※結果としては、「初期 と (初期 の二つをハイライトしたい。

typescript

1'use strict'; 2import * as vscode from 'vscode'; 3import * as fs from 'fs'; 4 5 6export function activate(context: vscode.ExtensionContext) { 7 console.log('Congratulations, your extension "semieditor" is now active!'); 8 9 const readsemiJson = JSON.parse(fs.readFileSync('C:\Users\specification\src\sample.json','utf8')); 10 11 context.subscriptions.push(vscode.commands.registerCommand('extension.color', () => { 12 vscode.window.showInformationMessage("Color Range Word"); 13 // 特定の単語に色付け 14 const timeWordList = readsemiJson.時間; 15 16 17 const timeWords: vscode.DecorationOptions[] = []; 18 const dependencyRelationWords: vscode.DecorationOptions[] = []; 19 20 var timeCount = 0; 21 22 //child -> parent(値域) semiについて 23 function fromObjecttoRange(WordList: any,foundWordList: vscode.DecorationOptions[],dependencyRelationList: vscode.DecorationOptions[],Count: number){ 24 const activeEditor = vscode.window.activeTextEditor; 25 const text = activeEditor.document.getText(); //ドキュメント取得 26 27 // // 取得したテキストを改行ごと(文章)に分割する 28 // const sentence = text.match(/[^\r\n]*(\r\n|\r|\n|$)/g); 29 var textArray = text.split(/\r\n|\r|\n/); 30 31 if(WordList === timeWordList){ 32 for(var i = 0; i < readsemiJson['時間'].length; i++){ 33 console.log(readsemiJson['時間'][i]); 34 const word = readsemiJson['時間'][i].split('=>'); 35 // const parentword = word[0]; 36 const rangeword = word[1]; 37 for(var j = 0; j < textArray.length; j++){ 38 console.log(textArray[j]); 39 if(textArray[j].indexOf(rangeword)){ 40 const startPos = activeEditor.document.positionAt(textArray[j].indexOf(rangeword)); 41 const endPos = activeEditor.document.positionAt(textArray[j].indexOf(rangeword) + rangeword.length); 42 // console.log(startPos, endPos); 43 const decoration = { range: new vscode.Range(startPos, endPos) }; 44 foundWordList.push(decoration); 45 } 46 } 47 } 48 return {foundWordList,dependencyRelationList,Count}; 49 } 50 } 51 function decorateWord() { 52 const activeEditor = vscode.window.activeTextEditor; 53 // const text = activeEditor.document.getText(); //ドキュメント取得 54 55 //時間 56 fromObjecttoRange(timeWordList,timeWords,dependencyRelationWords,timeCount); 57 58 activeEditor.setDecorations(timeMarkerDecoration,timeWords); 59 } 60 decorateWord(); 61 })); 62 63 //時間に色付け 64 const timeMarkerDecoration = vscode.window.createTextEditorDecorationType({ 65 'borderWidth': '1px', 66 'borderRadius': '2px', 67 'borderStyle': 'solid', 68 // 'backgroundColor': 'rgba(255, 0, 0, 0.3)', 69 'backgroundColor': 'rgba(128, 128, 0, 0.3)', 70 // 'color':'red' 71 'color':'orange' 72 }); 73}

JSON

1{ 2 "時間": [ 3 "なし=>(初期", 4 "なし=>「初期" 5 ] 6}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

このへんを参考にすると

Positionインスタンス生成時に渡す数値は、行・桁関係ない先頭からの文字数のようです。

とあり、提示のロジックでは、改行で分割したあと、その行内ポジションでrangeを作っているので、例えばどこかの行の先頭に「初期や(初期があると、最初の行の先頭の#に色がつくのではないでしょうか?

対策としては、テキストの先頭からのオフセットを保持し、jのforループの最後で現在の行の長さをオフセットに加算、次の行に進んだときのstartPos endPosを求めるときにオフセットを組み込むとよいのではないかと想像します。
またこのさい、改行文字そのもの(\rや\n、\r\n)が何文字とカウントされるかによって、オフセットをtextArray[j]のlengthより1または2文字増やす必要があるかもしれないと思います。

投稿2019/04/09 14:59

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syen2501

2019/04/11 01:57

回答ありがとうございます。 ちなみになのですが、テキストの先頭からのオフセットを保持というのはどうやってやるんでしょうか? 文を読み込む際に、文の長さを変数で保持しfor文でループする際に加算するということで良いのでしょうか?
papinianus

2019/04/11 02:05

それでいいと思います。 iのforのはじめあたりで、ゼロで初期化して、startPos=offSet+indexOfの値、としておいてjのループの最後でlengthを足す、感じかと。
syen2501

2019/04/11 03:33

回答ありがとうございます。 textArrayで改行で分割した後だと改行が記載されなくなるので改行での判定が出来ないのですが、 分割する前で判定を行うしかないのでしょうか?
papinianus

2019/04/15 13:58

var textArray = text.split(/(\r\n|\r|\n)/); ↑のところで、正規表現に()を含めると、splitに使った改行コードをtextArrayに含めることができます。例えばこの場合 > textArray = ["●#電源…判定する", "\r\n", ...]; のようになります(splitなので、偶数番目(インデクスが奇数の場所)に、正規表現でマッチした()で囲まれた部分が入ります) なので、かなりイヤーなコードになってしまいますが、処理をかならず2個ずつ操作していけば、分割後の判定も可能になります ``` //for(var j = 0; j < textArray.length; j++){ for(var j = 0; j < textArray.length; j+=2){ //2個ずつやる。でtextArray[j]が本文テキストで、textArray[j+1]が改行コード。そのlengthをオフセットに加算する ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問