[MATLAB] Text AnalyticsでDocumentationの必要な部分へのリンクを作成する

# はじめに
MATLABを使う際にとても便利なのが[ドキュメンテーション](https://jp.mathworks.com/help/matlab/)です. ここには, MathWorks製品である,

* MATLAB
* Simulink
* Toolbox

に含まれる関数の説明と使用例が詳細に記されており, これさえあればMATLABマスターになれます. そして, このドキュメンテーションを便利に使うのはMATLABを学ぶ人だけではありません. MATLABを教える立場にある人も, この[ドキュメンテーション](https://jp.mathworks.com/help/matlab/)を見ることで,
 
* 自分の考えは間違っていないかの確認
* 説明に使えそうなデモを見つけたり, そのアイデアをもらう

などができて, 大変便利です. また, この[ドキュメンテーション](https://jp.mathworks.com/help/matlab/)はインターネットで公開されているため, オンライン講習会などでも, 資料PDFにリンクを張るだけで相手に効果的な説明を行うことが可能です.

この記事では, そんな風にリンクを資料に貼ってMATLAB講習会を行っていたStudent Ambassadorが直面した問題とその解決方法について書きたいと思います.

この記事では, **MATLAB R2022a**及び, **Text Analytics Toolbox**を利用しています.

# [ドキュメンテーション](https://jp.mathworks.com/help/matlab/)のリンクを使っていた時に直面した問題
ここでは, MATLABでも基本的な関数, [plot](https://jp.mathworks.com/help/matlab/ref/plot.html)を題材にしてお話しします. 

MATLABのドキュメンテーションは非常に詳細に書かれています. これはとても親切な反面, MATLAB初心者の方に, 「この[リンク](https://jp.mathworks.com/help/matlab/ref/plot.html)を読めば, MATLABでどうやってグラフをかけるかわかるよ!!」と言ってしまうのは酷だと思っています. そのため, 講習会では, このドキュメンテーションを短い部分に分けながら紹介します. 例えば,

1. [ラインプロットの作成](https://jp.mathworks.com/help/matlab/ref/plot.html#btzpm1x)
2. [複数のラインのプロット](https://jp.mathworks.com/help/matlab/ref/plot.html#bt2458m)
3. ラインの色の変更
4. [ラインの幅の変更](https://jp.mathworks.com/help/matlab/ref/plot.html#btzi1ef-2)

だいたいこんな感じですね. 

お気づきですか? 
**"ラインの色の変更"のリンクがないんです.**

私はいつも, これらのリンクをドキュメンテーションの説明欄の「例」に付与されているリンク右クリックしてコピーしてきています. しかし, ドキュメンテーションに掲載されている例は, 全てが必ずリンクでつながっているわけではないのです.
![exampleLinkonDocument_processed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1635383/5663ead6-768e-4a6e-ad54-1795ecef292f.png)

しかし, リンクが張られていないからためにならないのか問われればそんなことはありません. 実際, 下のスクショのように, [plot関数のドキュメンテーション](https://jp.mathworks.com/help/matlab/ref/plot.html)でも, 実際のコードが載っている[いい例](https://jp.mathworks.com/help/matlab/ref/plot.html#btzpnds-1)があります.
![target.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1635383/701db30d-abce-af6c-77f8-af4e6504b485.png)

講習会の中で, これを紹介できないのはもったいない... ということで, この問題をMATLABを用いて解決することにしました.

# HTMLとURLのおさらい
まずは, htmlとurlのおさらいです. これまでに, ドキュメンテーションの中にある例を共有するために取得していたリンクは以下のような形式でした.

```
https://jp.mathworks.com/help/matlab/ref/plot.html#btzpm1x
```

これは, 以下のように分解できます.

![linkExplanation.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1635383/b7efa031-88f0-880a-7560-fc5b84c6420a.png)

ということで, ほしい例に割り振られたidさえ見つけられれば, リンクを作れるらしいということがわかってきました. そして, ドキュメンテーションのhtmlを読んでいくと, 以下のようなコードが見つかりました.

```
<h3 class="panel-title" id="btzpnds-1">ライン スタイル、色およびマーカーの指定<br/></h3>
```

このコードから, 必要な要素へのidが"btzpnds-1"であり, "h3"要素として格納されていることがわかりました.

# MATLABコードの開発
ここまでで, 必要な情報が得られたので, ここからは, MATLABで必要な要素へのリンクを作成するコードを開発していきます.

## MATLABでwebサイトのHTMLを読む
まず必要なのは, ドキュメンテーションのhtmlコードです. これはMATLAB本体にある[webread関数](https://jp.mathworks.com/help/matlab/ref/webread.html)で簡単に持ってくることができます.

```code:matlab
code = webread("https://jp.mathworks.com/help/matlab/ref/plot.html");
```

## 必要な例を表しているコードを見つける
ここでは, 取得したhtmlの中から, 必要な部分を見つけていきます. そのときに, Text Analytics Toolsboxにある, [htmlTree関数](https://jp.mathworks.com/help/textanalytics/ref/htmltree.html?s_tid=doc_ta)と[findElement関数](https://jp.mathworks.com/help/textanalytics/ref/htmltree.findelement.html?s_tid=doc_ta)を使用していきます. これらを用いることで, htmlコード内に存在するすべてのh3要素を抽出することができます. そして, それらの中から必要な例のタイトルを用いて, 必要な部分を抽出します.

```code:matlab
tree = htmlTree(code);
selector = "h3";
subtrees = string(findElement(tree,selector))
TF = contains(subtrees,"ライン スタイル、色およびマーカーの指定");
```

## id名を特定する
次に, 先ほどみつけたhtmlの中の例のタイトルを表すコードからid名を取得します. 

```code:matlab
eraseSpace_from_PossibleHTML = split(erase(possibleHTML(ii)," "),[" ",'"']);
TF = contains(eraseSpace_from_PossibleHTML,"id");
idName = eraseSpace_from_PossibleHTML(find(TF)+1);
```

## 必要な要素へのリンクを作成する
最後に, 必要な例へのリンクを完成させます.

```code:matlab
url_to_element = strcat("https://jp.mathworks.com/help/matlab/ref/plot.html","#",idName)
```

## 関数化
以上で説明した機能を含めた関数searchDocumentIDを作成しました.

```code:matlab
function createdurl = searchDocumentID(url,title,varargin)

%
% createdurl = searchDocumentID(url,title,'Selector',"selector") 
%   
%   -Inputs-
%   url         - URL of a MathWorks Documentation
%   title       - Searching title in the MathWorks Documentation
%   Selector    - HTML element that the "title" stored (Default is "h3")
%
%   -Output-
%   cratedurl   - url to the title in the MathWorks Documentation
%
%   --- Usage Example ---
%   
%   url = "https://jp.mathworks.com/help/matlab/ref/plot.html"
%   title = "ライン スタイル、色およびマーカーの指定"
%   url_to_plotColorChange = searchDocumentID(url,title)
%
%   ---------------------
%

    % Check Inputs
    defaultSelector = "h3";

    p = inputParser;
    validstring = @(x) (isstring(x) && length(x) == 1) || ischar(x);
    addRequired(p,'url',validstring);
    addRequired(p,'title',validstring);
    addParameter(p,'selector',defaultSelector,validstring);
    parse(p,url,title,varargin{:});

    % Get Documentation Web-site
    processed_url = p.Results.url;
    if (~contains(p.Results.url,"mathworks.com"))
        error("This code can apply only to MathWorks Documentation (url: %s)",p.Results.url);
        return
    elseif (contains(p.Results.url,"#"))
        tmp = split(p.Results.url,"#");
        processed_url = tmp(1);
    end
    code = webread(processed_url);

    % Find possible HTML codes by Text analytics
    tree = htmlTree(code);
    subtrees = string(findElement(tree,p.Results.selector));
    TF = contains(subtrees,p.Results.title);
    possibleHTML = subtrees(TF);
    if (length(possibleHTML) < 1)
        error("Cannot find %s in %s\n",p.Results.title,processed_url);
        return
    end

    % Get ID of serching element in HTML
    createdurl = [];
    for ii = 1:length(possibleHTML)
        eraseSpace_from_PossibleHTML = split(erase(possibleHTML(ii)," "),[" ",'"']);
        TF = contains(eraseSpace_from_PossibleHTML,"id");
        if (sum(TF) ~= 1)
            continue
        end
        idName = eraseSpace_from_PossibleHTML(find(TF)+1);
        createdurl = [createdurl;strcat(processed_url,"#",idName)];
    end

    % Check Outputs
    if (length(createdurl) < 1)
        error("Sorry, this code cannot apply this HTML\n");
        return
    end
end
```

# 試しに使ってみた
## 1. plot関数 - ライン スタイル、色およびマーカーの指定
```code:matlab
searchDocumentID("https://jp.mathworks.com/help/matlab/ref/plot.html","ライン スタイル、色およびマーカーの指定")
```

```text
ans = 

    "https://jp.mathworks.com/help/matlab/ref/plot.html#btzpnds-1"
```

**正解**

## 2. wordcloud関数 - Text Analytics Toolbox を使用したワード クラウドの作成
```code:matlab
searchDocumentID("https://jp.mathworks.com/help/matlab/ref/wordcloud.html","Text Analytics Toolbox を使用したワード クラウドの作成")
```

```text
Cannot find Text Analytics Toolbox を使用したワード クラウドの作成 in https://jp.mathworks.com/help/matlab/ref/wordcloud.html
```

**不正解**

## 3. wordcloud関数 - Text Analytics Toolbox
```code:matlab
searchDocumentID("https://jp.mathworks.com/help/matlab/ref/wordcloud.html","Text Analytics Toolbox")
```

```text
ans = 

    "https://jp.mathworks.com/help/matlab/ref/wordcloud.html#mw_75976109-9758-475c-8038-4e2379c7964d"
```

**正解**

日本語が不得手っぽいが, なんとか使えるレベルにはなっている気がする.

# おわりに
今回, この関数を作っておいたので, これからの講習会では, より効率よく資料を作っていこうと思います!!