【Rails】フォーム入力にマークダウン形式を適用したい

- **セキュリティに注意!!** 不特定多数が投稿できる場面で、マークダウン機能を導入と、XSS攻撃のリスク。**マークダウンでの投稿画面は、権限保持者に限定**するべきみたい。。
- マークダウン形式のgemは、[redcarpet](https://github.com/vmg/redcarpet)、言語での記述（シンタックスハイライト）は、[coderay](https://github.com/rubychan/coderay)を使用。

```rb:Gemfile
gem 'redcarpet', '~> 2.3.0'  # マークダウン形式での表示
gem 'coderay'                # シンタックスハイライト対応
```

- 流れは、 ヘルパーに導入したいマークダウン形式を記述 → 適用したいHTMLで、定義したメソッドを呼び出す。
 
# 適用したいフォーム
- 通常通り、投稿機能を作成すればOK。
- マークダウン形式で表示させたい部分のみ表記を変更。

```haml:例)マークダウン形式の導入(haml)
-# 投稿フォームは、通常通り
= form_for @post, local: true do |f|
  = f.text_area :problem, placeholder: "マークダウン形式OK"
  = f.submit "登録ボタン"

-# 投稿内容をマークダウン形式で表示
- @posts.each do |post|
  = post.problem            # マークダウン形式で表示されない
  = markdown(post.problem)  # マークダウン形式で表示される(ヘルパーで定義した markdownメソッドを呼び出す)
```

# ヘルパー作成
- ここに、導入したいマークダウン形式を指定。

```rb:例)application_helper.rb
module ApplicationHelper
  require "redcarpet"
  require "coderay"

  # マークダウン形式の導入（redcarpet）
  def markdown(text)
    options = {
      filter_html:     true,     # htmlを出力しない
      hard_wrap:       true,     # マークダウン中の空行をhtmlに置き換え
      space_after_headers: true, # # と文字の間にスペースを要求
    }

    extensions = {
      autolink:           true,  # <>で囲まれてなくてもリンクを認識
      no_intra_emphasis:  true,  # 単語中の強調を認識しない
      fenced_code_blocks: true,  # フェンスのあるコードブロックを認識
      strikethrough:      true,  # ~ 2つで取り消し線
      superscript:        true,  # ^ の後ろが上付き文字
      tables:             true,  # テーブルを認識
      underline:          true,  # 斜線(* *)
      highlight:          true,  # ハイライト(== ==)
      quote:              true,  # 引用符(" ")
      footnotes:          true,  # 脚注( ^[1] )

      # 今回は不使用なので、間違ってるかも。こんなんもあるらしい程度。(詳細は、https://github.com/vmg/redcarpet)
      xhtml: true,               # xhtml タグ出力(Render::XHTMLでは常に有効)
      lax_html_blocks: true,     # HTMLブロックの上下の空行を不要にする
      lax_spacing: true,         # HTMLブロックの空行を不要にする
      no_images: true,	         # img 要素を無効化
      no_links: true,	         # a 要素を無効化
      no_styles: true,           # style 要素を無効化
      safe_links_only: true,     # 安全なリンクだけ出力
      disable_indented_code_blocks: true, # 通常のマークダウンを認識しない。(行の先頭にある4つのスペースを持つテキストのコードブロックへの変換を無効化（ fencedcode_blocks: true と一緒の使用推奨))
      escape_html: true,         # HTMLタグをエスケープ。最優先され、:no_styles、:no_links、:no_images、:filter_html などは、削除ではなく、エスケープされる。
      with_toc_data: true,       # リンクの許可のため、出力HTMLのヘッダーにHTMLアンカー追加する
      prettify: true,            # prettyprintクラスを<code>google-code-prettifyタグに追加。
      link_attributes: true,     # リンクに追加する追加属性のハッシュ。
    }

    renderer = Redcarpet::Render::HTML.new(options)
    markdown = Redcarpet::Markdown.new(renderer, extensions)

    markdown.render(text).html_safe
  end
#------------------------------------------------------------------
  # 言語での記述（シンタックスハイライト）の導入（coderay）
    class HTMLwithCoderay < Redcarpet::Render::HTML
        def block_code(code, language)
            language = language.split(':')[0]

            case language.to_s
            when 'rb'         # rb も ruby　と認識させる。って意味。
                lang = 'ruby'
            when 'yml'
                lang = 'yaml'
            when 'css'
                lang = 'css'
            when 'html'
                lang = 'html'
            when ''
                lang = 'md'  # 空欄だとエラー?（Invalid id given:）
            else
                lang = language
            end

            CodeRay.scan(code, lang).div
        end
    end
end
```


# 参)よく使うマークダウン記法

|表示|記述|
|:--|:--|
|文字背景| *`* 、*``* で囲む|
|引用|>、 >> でネスト構造（※ 上下に空行）|
|h1,h2,..タグ|# h1、## h2|
|*emタグ(イタリック)*|*、_ で囲む|
|***emタグ(太字のイタリック)***|***、___ で囲む|
|**strongタグ(太字)**|**、__  で囲む|
|~~打ち消し~~|~~ で囲む|
|折りたたみ|＜details＞＜summary＞要約部分＜/summary＞＜/details＞　（下記参照↓）|
|リスト|* 、 + 、 - 、 数字. (※1. 1. のように同じ数字にしておくと便利)、＜dl＞＜dt＞親＜/dt＞＜dd＞子＜/dd＞＜/dl＞の書き方も可（下記参照↓）|
|[リンク](https://qiita.com/)|[リンク](url）|
|チェックボックス|- [ ]、 [x]（下記参照↓）|
|水平線|---、***|
|画像|![alt](URL）、![alt](URL "タイトル"）（下記参照↓）|
|テーブル| ｜｜|
|数式|言語 **math**で記述、**$** で挟むと文中にも組み込める。数式は、TeX記法を使用。（下記参照↓）|
|注釈[^1]|[^１] 脚注リンク、[^１]: 脚注のリンク先|
|上付き|^|
|ハイライト|== ==|
|絵文字|: で囲む。※ [絵文字チートシート](https://www.webfx.com/tools/emoji-cheat-sheet/)（下記参照↓）|
|Markdownを無効化(エスケープ)|\ を前につける|


```html:例)折りたたみの書き方
<details>
  <summary>**折りたたみの例**</summary>
  <div>
    サンプルコード↓↓ <!-- コードブロックの直前は空白行 -->

    ```rb:rb記法
      puts 'rubyでの表記'
    ```
  </div>
</details>
```

<details><summary>**折りたたみの例**</summary><div>
サンプルコード↓↓

```rb:rb記法
  puts 'rubyでの表記'
```
</div></details>


```html:例)Definition型でのリスト表示
<dl>
  <dt>親1</dt>
  <dd>子1</dd>
  <dt>親2</dt>
  <dd><strong>子</strong>2</dd>  <!-- HTMLの書き方！(タグ内はMarkdown記法は使用不可) -->
</dl>
```
<dl>
  <dt>親1</dt>
  <dd>子1</dd>
  <dt>親2</dt>
  <dd><strong>子</strong>2</dd>
</dl>


```html:例)チェックボックス表示
- [ ] チェックボックス1  <!-- 前後にスペース -->
- [x] チェックボックス2
```
- [ ] チェックボックス1
- [x] チェックボックス2

```html:例)画像の埋め込み
![Qiita](https://画像のURL/raw)
```
![Qiita](https://gyazo.com/cebd138d4a1ae24bb4a3a9efd81a460d/raw)

```html:例)数式の書き方
<!-- Tex記法 は、下記参照 -->
```math
  \left( \sum_{k=1}^n a_k b_k \right)^2 \leq
  \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
``｀

$x^2 + y^2 = 1$
$a = \{1, 2\}$ 
$a = \\{1, 2\\}$  <!-- コントロールシンボル（ \の後に記号が来る）を使いたい時は、エスケープになるので、 \\ と記載。 -->
```

```math
\left( \sum_{k=1}^n a_k b_k \right)^2 \leq
\left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
```
$x^2 + y^2 = 1$
$a = \{1, 2\}$
$a = \\{1, 2\\}$

```html:例)絵文字
:blush: 絵文字の埋め込み
```
:blush: 絵文字の埋め込み








# 参)TeX記法
- 基本的に、**`$`で囲んで使う**。

## 文字、記号

### ギリシャ文字

|大文字|tex記法|小文字|tex記法|
|:--|:--|:--|:--|
|$A$|A|$\alpha$|\alpha|
|$B$|B|$\beta$|\beta|
|$\Gamma$|\Gamma|$\gamma$|\gamma|
|$\Delta$|\Delta|$\delta$|\delta|
|$E$|E|$\epsilon$、$\varepsilon$|\epsilon、\varepsilon(変体文字)|
|$Z$|Z|$\zeta$|\zeta|
|$H$|H|$\eta$|\eta|
|$\Theta$|\Theta|$\theta$、$\vartheta$|\theta、\vartheta(変体文字)|
|$I$|I|$\iota$|\iota|
|$K$|K|$\kappa$|\kappa|
|$\Lambda$|\Lambda|$\lambda$|\lambda|
|$M$|M|$\mu$|\mu|
|$N$|N|$\nu$|\nu|
|$\Xi$|\Xi|$\xi$|\xi|
|$O$|O|$o$|o|
|$\Pi$|\Pi|$\pi$、$\varpi$|\pi、\varpi(変体文字)|
|$P$|P|$\rho$、$\varrho$|\rho、\varrho(変体文字)|
|$\Sigma$|\Sigma|$\sigma$、$\varsigma$|\sigma、\varsigma(変体文字)|
|$T$|T|$\tau$|\tau|
|$\Upsilon$|\Upsilon|$\upsilon$|\upsilon|
|$\Phi$|\Phi|$\phi$、$\varphi$|\phi、\varphi(変体文字)|
|$X$|X|$\chi$|\chi|
|$\Psi$|\Psi|$\psi$|\psi|
|$\Omega$|\Omega|$\omega$|\omega|

### 演算子や符号

|演算子|tex記法|
|:--|:--|
|$+$|+|
|$-$|-|
|$\times$|\times|
|$\div$|\div|
|$\pm$|\pm|
|$\mp$|\mp|
|$=$|=|
|$\neq$|\neq|
|$\equiv$|\equiv|
|$\sim$|\sim|
|$\simeq$|\simeq|
|$\fallingdotseq$|\fallingdotseq|
|$\risingdotseq$|\risingdotseq|
|$>$|>|
|$<$|<|
|$\geq$|\geq|
|$\geqq$|\geqq|
|$\leq$|\leq|
|$\leqq$|\leqq|
|$\gg$|\gg|
|$\ll$|\ll|


### その他の記号

|記号|表記|
|:--|:--|
|$\infty$|\infty|
|$\forall$|\forall|
|$\exists$|\exists|
|$\ell$|\ell|
|$\surd$|\surd|
|$\partial$|\partial|
|$\angle$|\angle|
|$\backslash$|\backslash|
|$\clubsuit$|\clubsuit|
|$\diamondsuit$|\diamondsuit|
|$\heartsuit$|\heartsuit|
|$\spadesuit$|\spadesuit|
|$\emptyset$|\diamondsuit|
|$\flat$|\flat|
|$\natural$|\natural|
|$\sharp$|\sharp|
|$\oplus$|\oplus|
|$\ominus$|\ominus|
|$\otimes$|\otimes|
|$\oslash$|\oslash|
|$\circ$、(例 $45^\circ$)|\circ、(例: 45^\circ)|
|$\cdot$|\cdot|
|$\cdots$|\cdots|
|$\bullet$|\bullet|
|$\in$|\in|
|$\ni$|\ni|
|$\notin$|\notin|
|$\subset$|\subset|
|$\supset$|\supset|
|$\subseteq$|\subseteq|
|$\supseteq$|\supseteq|
|$\cap$|\cap|
|$\cup$|\cup|
|$\emptyset$|\emptyset|
|$\underline{下線}$|\underline{下線}|
|$\overline{上線}$|\overline{上線}|


### 字体

|表示|表記|
|:--|:--|
|${\rm Roman}$|{\rm Roman}|
|${\it イタリック}$|{\it イタリック}|
|${\tt Typewriter}$|{\tt Typewriter}|
|${\bf太字}$|{\bf 太字}|
|${\sf SansSerif}$|{\sf SansSerif}|

### 文字サイズ

|表示|表記|
|:--|:--|
|${\tiny 最小}$|{\tiny 最小}|
|${\scriptsize スクリプトサイズ}$|{\scriptsize スクリプトサイズ}|
|${\small 小さく}$|{\small 小さく}|
|${\normalsize 普通}$|{\normalsize 普通}|
|${\large 大きく}$|{\large 大きく}|
|${\Large 大きく}$|{\Large 大きく}|
|${\LARGE 大きく}$|{\LARGE 大きく}|
|${\huge 大きく}$|{\huge 大きく}|
|${\Huge 大きく}$|{\Huge 大きく}|


## 括弧

|記号|表記|
|:--|:--|
|\{a}|\\{a}|
|$\lfloor a \rfloor$|\lfloor a \rfloor|
|$\lceil a \rceil$|\lceil a \rceil|
|$\langle a \rangle$|\langle a \rangle|


### 括弧の大きさ指定

|表示|表記|
|:--|:--|
|$\left( 標準 \right)$| \left( 標準 \right) |
|$\bigl( 標準+1 \bigr)$| \bigl( 標準+1 \bigr) |
|$\Bigl( 標準+2 \Bigr)$| \Bigl( 標準+2 \Bigr) |
|$\biggl( 標準+3 \biggr)$| \biggl( 標準+3 \biggr) |
|$\Biggl( 標準+4 \Biggr)$| \Biggl( 標準+4 \Biggr) |


## 数式

|表示|表記|
|:--|:--|
|$\frac{a}{b}$|\frac{a}{b}|
|$e^a$|e^a|
|$a_{b}$|a_{b}|
|$\exp a$|\exp a|
|$\sqrt{a}$|\sqrt{a}|
|$\sqrt[x]{a}$|\sqrt[x]{a}|
|$\log a$|\log a|
|$\log_a b$|\log_a b|
|$\ln a$|\ln a|
|$｜ｘ｜$|｜ｘ｜|
|${}_aC_b$|{}_aC_b|
|${}_aH_b$|{}_aH_b|
|${}_aP_b$|{}_aP_b|
|$lim_{n \to \infty}$|lim_{n \to \infty}|
|$\sum_{i=1}^{n}$|\sum_{i=1}^{n}|
|$\prod_{i=1}^{n}$|\prod_{i=1}^{n}|
|$\int_{a}^{b}$|\int_{a}^{b}|
|$\iint_{a}^{b}$|\iint_{a}^{b}|
|$\iiint_{a}^{b}$|\iiint_{a}^{b}|
|$\idotsint_{a}^{b}$|\idotsint_{a}^{b}|


### ベクトル

|表示|表記|
|:--|:--|
|$\vec{x}$|\vec{x}|
|$\overrightarrow{x}$|\overrightarrow{x}|
|$\hat{x}$|\hat{x}|


### 三角関数

|表示|表記|
|:--|:--|
|$\sin x$|\sin x|
|$\cos x$|\cos x|
|$\tan x$|\tan x|
|$\csc x$|\csc x|
|$\sec x$|\sec x|
|$\cot x$|\cot x|
|$\arcsin x$|\arcsin x|
|$\arccos x$|\arccos x|
|$\arctan x$|\arctan x|
|$\sinh x$|\sinh x|
|$\cosh x$|\cosh x|
|$\tanh x$|\tanh x|