Repository: richcat-dev/richcat (language: python)

Issue:
jupyterのバージョンによって `--clear-output` されない不具合がある
https://stackoverflow.com/questions/28908319/how-to-clear-jupyter-notebooks-output-in-all-cells-from-the-linux-terminal

jupyterのバージョンによって`--clear-output`が効かないらしい

_Originally posted by @ShotaroKataoka in https://github.com/richcat-dev/richcat/issues/138#issuecomment-1054848332_


Discussion / hints:

Fix patch:
diff --git a/.actrc b/.actrc
new file mode 100644
index 0000000..85b04f0
--- /dev/null
+++ b/.actrc
@@ -0,0 +1,3 @@
+-P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest
+-P ubuntu-20.04=ghcr.io/catthehacker/ubuntu:act-20.04
+-P ubuntu-18.04=ghcr.io/catthehacker/ubuntu:act-18.04
diff --git a/.bashrc b/.bashrc
new file mode 100644
index 0000000..ccbe7bb
--- /dev/null
+++ b/.bashrc
@@ -0,0 +1,11 @@
+# Colorize prompt
+export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
+
+# Set less command options
+export LESS="-F -g -i -M -R -S -w -X -z-4"
+
+# Alias for act command
+alias act="~/bin/act"
+
+# Alias for Jupyter Lab
+alias jl='jupyter lab --port 8888 --ip=* --allow-root'
\ No newline at end of file
diff --git a/.codacy.yml b/.codacy.yml
index cccc116..eb56e62 100644
--- a/.codacy.yml
+++ b/.codacy.yml
@@ -1,2 +1,4 @@
 exclude_paths:
   - 'debug/**'
+  - 'docs/**'
+  - 'doc/**'
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
new file mode 100644
index 0000000..6da6113
--- /dev/null
+++ b/.github/workflows/codecov.yml
@@ -0,0 +1,40 @@
+name: Codecov
+on:
+  pull_request:
+    branches: 
+    - 'main'
+    - 'develop'
+jobs:
+  run:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os: [ubuntu-latest]
+    env:
+      OS: ${{ matrix.os }}
+      PYTHON: '3.7'
+    steps:
+    - uses: actions/checkout@master
+    - name: Setup Python
+      uses: actions/setup-python@master
+      with:
+        python-version: 3.7
+    - name: Generate coverage report
+      run: |
+        python -m pip install --upgrade pip
+        pip install pytest pytest-cov
+        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+        ./workflow-test.sh cov CI
+    - name: Upload coverage to Codecov
+      uses: codecov/codecov-action@v1
+      with:
+        token: ${{ secrets.CODECOV_TOKEN }}
+        file: ./coverage.xml
+        files: ./coverage1.xml,./coverage2.xml
+        directory: ./coverage/reports/
+        flags: unittests
+        env_vars: OS,PYTHON
+        name: codecov-umbrella
+        fail_ci_if_error: true
+        path_to_write_report: ./coverage/codecov_report.txt
+        verbose: true
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
index a2ef105..bc92586 100644
--- a/.github/workflows/python-package.yml
+++ b/.github/workflows/python-package.yml
@@ -7,10 +7,6 @@ on:
   push:
     branches: 
     - 'develop'
-    - 'topic/**'
-    - 'release/**'
-    - 'hotfix/**'
-    - 'main'
   pull_request:
     branches: 
     - 'main'
@@ -22,7 +18,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ['3.6', '3.7', '3.8']
+        python-version: ['3.6', '3.7', '3.8', '3.9']
 
     steps:
     - uses: actions/checkout@v2
@@ -43,4 +39,4 @@ jobs:
         flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=debug/**
     - name: Test with pytest
       run: |
-        pytest
+        ./workflow-test.sh
diff --git a/.github/workflows/sphinx-build.yml b/.github/workflows/sphinx-build.yml
new file mode 100644
index 0000000..fb10d36
--- /dev/null
+++ b/.github/workflows/sphinx-build.yml
@@ -0,0 +1,34 @@
+name: Sphinx Build
+
+on:
+  push:
+    branches: main
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.7
+
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          python -m pip install -r ./requirements.txt
+
+      - name: Build
+        run: |
+          make sphinx-deploy
+
+      - name: Deploy
+        uses: peaceiris/actions-gh-pages@v3
+        with:
+          github_token: ${{ secrets.GITHUB_TOKEN }}
+          publish_branch: gh-pages
+          publish_dir: ./sphinx/_build
diff --git a/.github/workflows/update-ext2alias-dict.yml b/.github/workflows/update-ext2alias-dict.yml
new file mode 100644
index 0000000..51b4e73
--- /dev/null
+++ b/.github/workflows/update-ext2alias-dict.yml
@@ -0,0 +1,40 @@
+name: Update extension-to-alias dictionalies
+
+on:
+  push:
+    branches:
+      - develop
+
+jobs:
+  update:
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.7
+
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          python -m pip install -r ./requirements.txt
+
+      - name: Update
+        run: |
+          python ./richcat/modules/consts/_ext2alias_dic_generator.py
+
+      - name: Push
+        run: |
+          git remote set-url origin https://github-actions:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}
+          git config --global user.name "${GITHUB_ACTOR}"
+          git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
+          git add ./richcat/modules/consts/_ext2alias_dic_generator.py
+          git diff --exit-code --quiet ./richcat/modules/consts/_ext2alias_dic_generator.py
+          if [[ $? -eq 1 ]]; then
+            git commit -m "Update dictionalies";
+            git push origin HEAD:${GITHUB_REF};
+          fi
diff --git a/.github/workflows/upload-to-pypi.yml b/.github/workflows/upload-to-pypi.yml
new file mode 100644
index 0000000..bef9517
--- /dev/null
+++ b/.github/workflows/upload-to-pypi.yml
@@ -0,0 +1,78 @@
+name: Upload to PyPI
+
+on:
+  push:
+    tags:
+      - v*
+
+jobs:
+  check_version:
+    runs-on: ubuntu-latest
+
+    outputs:
+      version: ${{ steps.get_version_in_branch.outputs.version_in_branch }}
+      version_matched: ${{ steps.compare_version.outputs.matched }}
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.7
+
+      - name: Extract richcat version from branch name
+        id: get_version_in_branch
+        run: echo "::set-output name=version_in_branch::$(echo ${GITHUB_REF#refs/tags/} | sed 's/v//')"
+
+      - name: Get richcat version from code
+        id: get_version_in_code
+        run: echo "::set-output name=version_in_code::$(python ./scripts/get_version.py)"
+
+      - name: Compare version
+        id: compare_version
+        run: echo "::set-output name=matched::$([[ ${{ steps.get_version_in_branch.outputs.version_in_branch }} == ${{ steps.get_version_in_code.outputs.version_in_code }} ]]; echo $?)"
+
+  release_richcat:
+    runs-on: ubuntu-latest
+    needs: check_version
+    if: ${{ needs.check_version.outputs.version_matched == 0 }}
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.7
+
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          python -m pip install wheel twine
+
+      - name: Build
+        run: |
+          rm -rf ./richcat.egg-info/ dist/
+          python setup.py bdist_wheel
+
+      - name: Publish package to PyPI
+        id: upload
+        if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
+        uses: pypa/gh-action-pypi-publish@release/v1
+        with:
+          user: __token__
+          password: ${{ secrets.PYPI_API_TOKEN }}
+
+      - name: Create release
+        if: steps.upload.conclusion == 'success'
+        uses: actions/create-release@v1
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          tag_name: v${{ needs.check_version.outputs.version }}
+          release_name: Release v${{ needs.check_version.outputs.version }}
+          draft: false
+          prerelease: false
diff --git a/.gitignore b/.gitignore
index 308dc6e..2642d86 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,8 @@ share/python-wheels/
 .installed.cfg
 *.egg
 MANIFEST
+.pypirc
+.python_history
 
 # PyInstaller
 #  Usually these files are written by a python script from a template
@@ -69,13 +71,21 @@ instance/
 .scrapy
 
 # Sphinx documentation
-docs/_build/
+sphinx/*
+!sphinx/_static/
+!sphinx/_templates/
+!sphinx/index.rst
+!sphinx/conf.py
+!sphinx/make.bat
+!sphinx/Makefile
 
 # PyBuilder
 target/
 
 # Jupyter Notebook
-.ipynb_checkpoints
+.ipynb_checkpoints/
+.jupyter/
+.local/
 
 # IPython
 profile_default/
@@ -130,3 +140,9 @@ dmypy.json
 
 # VSCode Remote Container
 .vscode/
+
+# bash
+.bash_history
+
+# act
+.secrets
\ No newline at end of file
diff --git a/.pypirc.sample b/.pypirc.sample
new file mode 100644
index 0000000..7b0e741
--- /dev/null
+++ b/.pypirc.sample
@@ -0,0 +1,14 @@
+[distutils]
+index-servers =
+  pypi
+  testpypi
+
+[pypi]
+repository: https://upload.pypi.org/legacy/
+username: 
+password: 
+
+[testpypi]
+repository: https://test.pypi.org/legacy/
+username: 
+password: 
\ No newline at end of file
diff --git a/.secrets.sample b/.secrets.sample
new file mode 100644
index 0000000..0c6a33d
--- /dev/null
+++ b/.secrets.sample
@@ -0,0 +1,1 @@
+GITHUB_TOKEN=
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..063fc45
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,16 @@
+# Base image
+FROM python:3.7
+
+# Environment
+ENV HOME /home
+WORKDIR $HOME
+COPY .bashrc requirements.txt $HOME/
+
+# Installl commands
+RUN apt-get update && apt-get upgrade -y \
+    && apt-get install -y \
+    less
+
+# Install Python libraries
+RUN pip install --upgrade pip \
+    && pip install -r $HOME/requirements.txt
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..d4e7962
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,18 @@
+SPHINXDIR = sphinx
+PROJECTNAME = richcat
+PROJECTDIR = ${PROJECTNAME}
+DEPLOYDIR = ${SPHINXDIR}/_build
+
+
+.PHONY: apidoc
+apidoc:
+	sphinx-apidoc -f -H ${PROJECTNAME} -o "${SPHINXDIR}" "${PROJECTDIR}"
+
+.PHONY: autobuild
+autobuild:
+	sphinx-autobuild --host 0.0.0.0 -b html "${SPHINXDIR}" "${DEPLOYDIR}"
+
+.PHONY: publicbuild
+publicbuild:
+	sphinx-apidoc -f -H ${PROJECTNAME} -o "${SPHINXDIR}" "${PROJECTDIR}"
+	sphinx-build -b html "${SPHINXDIR}" "${DEPLOYDIR}"
\ No newline at end of file
diff --git a/README.md b/README.md
index 92fe7fa..dd8b74f 100644
--- a/README.md
+++ b/README.md
@@ -1,42 +1,133 @@
 ![Python package](https://github.com/richcat-dev/richcat/workflows/Python%20package/badge.svg)
 [![Codacy Badge](https://api.codacy.com/project/badge/Grade/4e61b411095d4d3292e2a3e169aa0f35)](https://app.codacy.com/gh/richcat-dev/richcat?utm_source=github.com&utm_medium=referral&utm_content=richcat-dev/richcat&utm_campaign=Badge_Grade)
 [![Downloads](https://pepy.tech/badge/richcat)](https://pepy.tech/project/richcat)
+
 # richcat
+
 - `richcat` is a `cat` command decorated by [rich](https://github.com/willmcgugan/rich) which is Python library.
 - Working on Python.
 
 ## Features
 
 ### Syntax hilighting
-![](doc/img/index-html.jpg)
 
-### Support viewer
+![image](https://user-images.githubusercontent.com/55144709/152114834-9172b501-269a-4044-9889-94c92346c5ff.png)
 
-#### Markdown
-![](doc/img/sample-md.jpg)
+### Support viewer
 
-#### CSV
-![](doc/img/table-csv.jpg)
+| Markdown                                                                                                        | CSV                                                                                                             | Jupyter Notebook                                                                                                |
+| --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
+| ![image](https://user-images.githubusercontent.com/55144709/152116094-d20ea35a-5dbd-441c-b668-2a3f408caaaf.png) | ![image](https://user-images.githubusercontent.com/55144709/152116330-e9a391a0-0491-4b3b-82f9-7a56e789a273.png) | ![image](https://user-images.githubusercontent.com/55144709/154985162-d177e0ac-4f26-47e2-a49b-5008883e541f.png) |
 
 ### Automatic paging
-By default, `richcat` pipes its own output to a pager. If you wouldn't rather pager, use `--disable-pager` option.
+
+By default, `richcat` pipes its own output to a pager. If you wouldn't rather pager, use `--style=nopager` option.
+
+![image](https://user-images.githubusercontent.com/55144709/152116597-fdaca73f-9c0d-4b56-894c-e384dba84d96.png)
+
+### Support Python import
+
+Import on Python console:
+
+![image](https://user-images.githubusercontent.com/55144709/154991230-006518c7-f5a4-43c4-82f4-3390d84eb64d.png)
+
+Import on Jupyter Lab:
+
+![image](https://user-images.githubusercontent.com/55144709/154992180-07477488-c2d5-4e72-acbe-1954171d589a.png)
 
 ## Installation
+
 ```
-$ pip install richcat
+pip install richcat
 ```
 
 ## Usage
+
 Display a file contents on the terminal.
+
+example:
+
 ```
-$ richcat README.md
+richcat table.csv
 ```
 
 Use `-t` option, you can choose highlight.
+
+example:
+
+```
+richcat table.csv -t text
+```
+
+Use `--style=header` option if you use the header in a CSV file.
+
+example:
+
+```sh
+richcat table.csv --style=header
+```
+
+| `--style=noheader` (default)                                                                                    | `--style=header`                                                                                                |
+| --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
+| ![image](https://user-images.githubusercontent.com/55144709/152151519-a95c262d-9074-47f2-ada8-b5dae6a4866c.png) | ![image](https://user-images.githubusercontent.com/55144709/152151220-9e7e8829-109e-42ed-ad78-96f145fbf222.png) |
+
+If you want to use `richcat` in Python, you can use the following example.
+
+example:
+
+```python
+>>> from richcat import richcat
+>>> richcat("table.csv")
 ```
-$ richcat README.md -t text
+
+## Options
+
+The options that can be specified in `richcat` are as follows:
+
+| option                          | explanation                                                                                          | example                     |
+| ------------------------------- | ---------------------------------------------------------------------------------------------------- | --------------------------- |
+| `-h`, `--help`                  | Show help in English.                                                                                |
+| `-V`, `--version`               | Show version.                                                                                        |
+| `-t`, `--filetype <STRING>`     | Specify file type.                                                                                   | `--filetype python`         |
+| `-w`, `--width <INT or FLOAT>`  | Set print width. <br> If width>1, set print width direct. <br> If width<1, set print width percent.' | `--width 80`, `--width 0.5` |
+| `-c`, `--color-system <STRING>` | Choose color system. <br> ['standard', '256', 'truecolor', 'windows']                                |
+| `--style <STRING>`              | Set styles. <br> ['[no]header', '[no]pager']                                                         | `--style=header,nopager`    |
+
+## Development
+
+If you want to develop richcat, please follow the steps below.
+
+1. Build the development environment.
+
+```
+$ git clone git@github.com:richcat-dev/richcat.git
+$ docker-compose build
+```
+
+2. Start the development environment.
+
 ```
+$ docker-compose up -d
+```
+
+3. Go inside the launched Docker container to develop.
+
+```
+$ docker exec -it <CONTAINER_ID> /bin/bash
+```
+
+You can view the API document of richcat under development at the following URL.
+
+- http://localhost:8000/
+
+You can update `richcat` API documentation with the following command.
+
+```
+$ cd ~
+$ make sphinx-apidoc
+```
+
+## Contributors
 
-# Contributors!
 - [@yamamoto-yuta](https://github.com/yamamoto-yuta) (Maintainer, **main contributor!**)
 - [@ShotaroKataoka](https://github.com/ShotaroKataoka) (Maintainer)
diff --git a/bin/act b/bin/act
new file mode 100755
index 0000000..6f98593
Binary files /dev/null and b/bin/act differ
diff --git a/debug/.vim b/debug/.vim
new file mode 100644
index 0000000..81be77c
--- /dev/null
+++ b/debug/.vim
@@ -0,0 +1,65 @@
+" setting
+"文字コードをUFT-8に設定
+set fenc=utf-8
+" バックアップファイルを作らない
+set nobackup
+" スワップファイルを作らない
+set noswapfile
+" 編集中のファイルが変更されたら自動で読み直す
+set autoread
+" バッファが編集中でもその他のファイルを開けるように
+set hidden
+" 入力中のコマンドをステータスに表示する
+set showcmd
+
+
+" 見た目系
+" 行番号を表示
+set number
+" 現在の行を強調表示
+set cursorline
+" 現在の行を強調表示（縦）
+"set cursorcolumn
+" 行末の1文字先までカーソルを移動できるように
+set virtualedit=onemore
+" インデントはスマートインデント
+set smartindent
+" ビープ音を可視化
+set visualbell
+" 括弧入力時の対応する括弧を表示
+set showmatch
+" ステータスラインを常に表示
+set laststatus=2
+" コマンドラインの補完
+set wildmode=list:longest
+" 折り返し時に表示行単位での移動できるようにする
+nnoremap j gj
+nnoremap k gk
+" シンタックスハイライトの有効化
+syntax enable
+
+" Tab系
+" 不可視文字を可視化(タブが「▸-」と表示される)
+set list listchars=tab:\▸\-
+" Tab文字を半角スペースにする
+set expandtab
+" 行頭以外のTab文字の表示幅（スペースいくつ分）
+set tabstop=2
+" 行頭でのTab文字の表示幅
+set shiftwidth=2
+
+
+" 検索系
+" 検索文字列が小文字の場合は大文字小文字を区別なく検索する
+set ignorecase
+" 検索文字列に大文字が含まれている場合は区別して検索する
+set smartcase
+" 検索文字列入力時に順次対象文字列にヒットさせる
+set incsearch
+" 検索時に最後まで行ったら最初に戻る
+set wrapscan
+" 検索語をハイライト表示
+set hlsearch
+" ESC連打でハイライト解除
+nmap <Esc><Esc> :nohlsearch<CR><Esc>
+
diff --git a/debug/Dockerfile b/debug/Dockerfile
new file mode 100644
index 0000000..ab54274
--- /dev/null
+++ b/debug/Dockerfile
@@ -0,0 +1,33 @@
+# Base image
+FROM python:3.7
+
+# Environment
+ENV HOME /home
+WORKDIR $HOME
+COPY .bashrc requirements.txt $HOME/
+
+# Install Commands
+RUN apt-get update && apt-get upgrade -y \
+  && apt-get install -y \
+    git \
+    vim
+
+# Install Python libraries
+RUN pip install --upgrade pip \
+  && pip install -r $HOME/requirements.txt
+
+# Install Node.js
+RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
+  && apt-get install -y nodejs \
+  && npm install n -g \
+  && n stable \
+  && apt-get purge -y nodejs npm
+
+# Install Jupyter Lab Extensions
+RUN pip install ipywidgets \
+  && jupyter nbextension enable --py --sys-prefix widgetsnbextension \
+  && jupyter labextension install \
+    @jupyter-widgets/jupyterlab-manager \
+    @lckr/jupyterlab_variableinspector \
+    @jupyterlab/toc
+
diff --git a/debug/Untitled.ipynb b/debug/Untitled.ipynb
new file mode 100644
index 0000000..16ce10a
--- /dev/null
+++ b/debug/Untitled.ipynb
@@ -0,0 +1,238 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The autoreload extension is already loaded. To reload it, use:\n",
+      "  %reload_ext autoreload\n"
+     ]
+    }
+   ],
+   "source": [
+    "%load_ext autoreload\n",
+    "%autoreload 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m1 \u001b[0m\u001b[38;5;149;48;5;235mecho\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;222;48;5;235m\"hello world\"\u001b[0m\u001b[48;5;235m    \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m2 \u001b[0m\u001b[38;5;149;48;5;235ma\u001b[0m\u001b[38;5;204;48;5;235m=\u001b[0m\u001b[38;5;149;48;5;235mbbb\u001b[0m\u001b[48;5;235m                 \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m3 \u001b[0m\u001b[38;5;149;48;5;235mecho\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;149;48;5;235m$a\u001b[0m\u001b[48;5;235m               \u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "!richcat test.js"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from richcat import richcat"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m1 \u001b[0m\u001b[38;5;231;48;5;235mecho\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;222;48;5;235m\"\u001b[0m\u001b[38;5;222;48;5;235mhello world\u001b[0m\u001b[38;5;222;48;5;235m\"\u001b[0m\u001b[48;5;235m                                                                              \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m2 \u001b[0m\u001b[38;5;231;48;5;235ma\u001b[0m\u001b[38;5;204;48;5;235m=\u001b[0m\u001b[38;5;231;48;5;235mbbb\u001b[0m\u001b[48;5;235m                                                                                           \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m3 \u001b[0m\u001b[38;5;231;48;5;235mecho\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;126;48;5;52m$\u001b[0m\u001b[38;5;231;48;5;235ma\u001b[0m\u001b[48;5;235m                                                                                         \u001b[0m\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": [
+       "<rich.jupyter.JupyterRenderable at 0x7fbf7508c760>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "richcat('test.py', width=100)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m1 \u001b[0m\u001b[38;5;231;48;5;235mecho\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;222;48;5;235m\"\u001b[0m\u001b[38;5;222;48;5;235mhello world\u001b[0m\u001b[38;5;222;48;5;235m\"\u001b[0m\u001b[48;5;235m                                  \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m2 \u001b[0m\u001b[38;5;231;48;5;235ma\u001b[0m\u001b[38;5;204;48;5;235m=\u001b[0m\u001b[38;5;231;48;5;235mbbb\u001b[0m\u001b[48;5;235m                                               \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m3 \u001b[0m\u001b[38;5;231;48;5;235mecho\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;126;48;5;52m$\u001b[0m\u001b[38;5;231;48;5;235ma\u001b[0m\u001b[48;5;235m                                             \u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "!richcat test.py -w 0.7"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "╭────────────────────────────────────────────────╮\n",
+      "│                                                │\n",
+      "│   ╔════════════════════════════════════════╗   │\n",
+      "│   ║                \u001b[1mheader 1\u001b[0m                ║   │\n",
+      "│   ╚════════════════════════════════════════╝   │\n",
+      "│                                                │\n",
+      "│                                                │\n",
+      "│                    \u001b[1;4mheader 2\u001b[0m                    │\n",
+      "│                                                │\n",
+      "│                    \u001b[1mheader 3\u001b[0m                    │\n",
+      "│                                                │\n",
+      "│                    \u001b[1;2mheader 4\u001b[0m                    │\n",
+      "│                                                │\n",
+      "│                    \u001b[4mheader 5\u001b[0m                    │\n",
+      "│                                                │\n",
+      "│                    \u001b[3mheader 6\u001b[0m                    │\n",
+      "│                                                │\n",
+      "│   \u001b[1;33m • \u001b[0mlist                                      │\n",
+      "│   \u001b[1;33m   \u001b[0m\u001b[1;33m • \u001b[0mabc                                    │\n",
+      "│   \u001b[1;33m   \u001b[0m\u001b[1;33m • \u001b[0mdef                                    │\n",
+      "│   \u001b[1;33m   \u001b[0m\u001b[1;33m   \u001b[0m\u001b[1;33m • \u001b[0mghi                                 │\n",
+      "│   \u001b[1;33m   \u001b[0m\u001b[1;33m   \u001b[0m\u001b[1;33m • \u001b[0mjkl                                 │\n",
+      "│                                                │\n",
+      "│   \u001b[1;33m 1 \u001b[0mnumerical list                            │\n",
+      "│   \u001b[1;33m 2 \u001b[0mnumerical list                            │\n",
+      "│                                                │\n",
+      "│   \u001b[2m┌────────────────────────────────────────┐\u001b[0m   │\n",
+      "│   \u001b[2m│\u001b[0m \u001b[48;5;235mimport numpy as np                   \u001b[0m  \u001b[2m│\u001b[0m   │\n",
+      "│   \u001b[2m│\u001b[0m \u001b[48;5;235mprint(np.array([1,2,3,4]))           \u001b[0m  \u001b[2m│\u001b[0m   │\n",
+      "│   \u001b[2m└────────────────────────────────────────┘\u001b[0m   │\n",
+      "│                                                │\n",
+      "│   aaaaaaaaa                                    │\n",
+      "│                                                │\n",
+      "│   \u001b[2m┌────────────────────────────────────────┐\u001b[0m   │\n",
+      "│   \u001b[2m│\u001b[0m \u001b[38;5;204;48;5;235mimport\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;231;48;5;235mnumpy\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;117;48;5;235mas\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;231;48;5;235mnp\u001b[0m\u001b[48;5;235m                   \u001b[0m  \u001b[2m│\u001b[0m   │\n",
+      "│   \u001b[2m│\u001b[0m \u001b[38;5;231;48;5;235mprint\u001b[0m\u001b[38;5;231;48;5;235m(\u001b[0m\u001b[38;5;231;48;5;235mnp\u001b[0m\u001b[38;5;204;48;5;235m.\u001b[0m\u001b[38;5;231;48;5;235marray\u001b[0m\u001b[38;5;231;48;5;235m(\u001b[0m\u001b[38;5;231;48;5;235m[\u001b[0m\u001b[38;5;147;48;5;235m1\u001b[0m\u001b[38;5;231;48;5;235m,\u001b[0m\u001b[38;5;147;48;5;235m2\u001b[0m\u001b[38;5;231;48;5;235m,\u001b[0m\u001b[38;5;147;48;5;235m3\u001b[0m\u001b[38;5;231;48;5;235m,\u001b[0m\u001b[38;5;147;48;5;235m4\u001b[0m\u001b[38;5;231;48;5;235m]\u001b[0m\u001b[38;5;231;48;5;235m)\u001b[0m\u001b[38;5;231;48;5;235m)\u001b[0m\u001b[48;5;235m           \u001b[0m  \u001b[2m│\u001b[0m   │\n",
+      "│   \u001b[2m└────────────────────────────────────────┘\u001b[0m   │\n",
+      "│                                                │\n",
+      "│   ╔════════════════════════════════════════╗   │\n",
+      "│   ║                 \u001b[1mtable\u001b[0m                  ║   │\n",
+      "│   ╚════════════════════════════════════════╝   │\n",
+      "│                                                │\n",
+      "│   | aaa | bbb | ccc | | --- | --- | --- | |    │\n",
+      "│   bbb | 344 | 535 | | bbb | 344 | 535 | |      │\n",
+      "│   bbb | 344 | 535 | | bbb | 344 | 535 | |      │\n",
+      "│   bbb | 344 | 535 |                            │\n",
+      "│                                                │\n",
+      "╰────────────────────────────────────────────────╯\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": [
+       "<rich.jupyter.JupyterRenderable at 0x7fbf75075d90>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "richcat('sample.md', width=50)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "error1000: raise error1. hello!\n"
+     ]
+    }
+   ],
+   "source": [
+    "class MyException1(Exception):\n",
+    "    def __init__(self, *arg):\n",
+    "        self.arg=arg\n",
+    "\n",
+    "class MyException2(Exception):\n",
+    "    pass\n",
+    "\n",
+    "def check_error(error):\n",
+    "    if error.__class__==MyException1:\n",
+    "        print(f\"error{error.arg[0]}: raise error1. {error.arg[1]}\")\n",
+    "    elif error.__class__==MyException2:\n",
+    "        print(\"error: raise error2\")\n",
+    "    else:\n",
+    "        raise error\n",
+    "\n",
+    "def main():\n",
+    "    raise MyException1('1000', 'hello!')\n",
+    "    #  raise MyException2\n",
+    "    #  raise ZeroDivisionError\n",
+    "\n",
+    "try:\n",
+    "    main()\n",
+    "except Exception as e:\n",
+    "    check_error(e)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/debug/debug.md b/debug/debug.md
new file mode 100644
index 0000000..4c0e51d
--- /dev/null
+++ b/debug/debug.md
@@ -0,0 +1,5 @@
+# header 1
+
+iiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao
+
+
diff --git a/debug/docker-compose.yml b/debug/docker-compose.yml
new file mode 100644
index 0000000..267249c
--- /dev/null
+++ b/debug/docker-compose.yml
@@ -0,0 +1,21 @@
+version: '3'
+
+services:
+
+  model:
+    build: ./model
+    container_name: qa-app_model
+    tty: true
+    volumes:
+      - ./model:/home/model
+    ports:
+      - "5000:5000"
+
+  web:
+    build: ./web
+    container_name: qa-app_web
+    tty: true
+    volumes:
+      - ./web:/home/web
+    ports:
+      - "8080:8080"
diff --git a/debug/index.html b/debug/index.html
new file mode 100644
index 0000000..238c5cd
--- /dev/null
+++ b/debug/index.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <meta charset="utf-8">
+    <title>sample</title>
+    <link rel="stylesheet" href="style.css">
+</head>
+
+<body>
+    <h1>Sample</h1>
+    <div>
+        Sample text
+    </div>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/debug/javascript.js b/debug/javascript.js
new file mode 100644
index 0000000..c6ab2b6
--- /dev/null
+++ b/debug/javascript.js
@@ -0,0 +1,6 @@
+var x, y, z; // Declare 3 variables
+x = 5; // Assign the value 5 to x
+y = 6; // Assign the value 6 to y
+z = x + y; // Assign the sum of x and y to z
+
+document.getElementById("demo").innerHTML = "The value of z is " + z + ".";
\ No newline at end of file
diff --git a/debug/json.json b/debug/json.json
new file mode 100644
index 0000000..2f9f982
--- /dev/null
+++ b/debug/json.json
@@ -0,0 +1,93 @@
+{
+    "metadata": {
+        "language_info": {
+            "codemirror_mode": {
+                "name": "ipython",
+                "version": 3
+            },
+            "file_extension": ".py",
+            "mimetype": "text/x-python",
+            "name": "python",
+            "nbconvert_exporter": "python",
+            "pygments_lexer": "ipython3",
+            "version": "3.8.5-final"
+        },
+        "orig_nbformat": 2,
+        "kernelspec": {
+            "name": "python3",
+            "display_name": "Python 3.8.5 64-bit",
+            "metadata": {
+                "interpreter": {
+                    "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
+                }
+            }
+        }
+    },
+    "nbformat": 4,
+    "nbformat_minor": 2,
+    "cells": [{
+            "cell_type": "code",
+            "execution_count": 3,
+            "metadata": {},
+            "outputs": [{
+                "output_type": "stream",
+                "name": "stdout",
+                "text": [
+                    "Hello\nWorld\n"
+                ]
+            }],
+            "source": [
+                "print('Hello')\n",
+                "print('World')"
+            ]
+        },
+        {
+            "source": [
+                "# markdown test\n",
+                "- hoge\n",
+                "    - hoge\n",
+                "```\n",
+                "$ hoge\n",
+                "```"
+            ],
+            "cell_type": "markdown",
+            "metadata": {}
+        },
+        {
+            "cell_type": "code",
+            "execution_count": 1,
+            "metadata": {},
+            "outputs": [{
+                    "output_type": "stream",
+                    "name": "stdout",
+                    "text": [
+                        "Welcome\nYeah\n"
+                    ]
+                },
+                {
+                    "output_type": "error",
+                    "ename": "NameError",
+                    "evalue": "name 'b' is not defined",
+                    "traceback": [
+                        "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+                        "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
+                        "\u001b[0;32m<ipython-input-1-2092cbed5dce>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Welcome'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Yeah'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+                        "\u001b[0;31mNameError\u001b[0m: name 'b' is not defined"
+                    ]
+                }
+            ],
+            "source": [
+                "print('Welcome')\n",
+                "print('Yeah')\n",
+                "b"
+            ]
+        },
+        {
+            "cell_type": "code",
+            "execution_count": null,
+            "metadata": {},
+            "outputs": [],
+            "source": []
+        }
+    ]
+}
\ No newline at end of file
diff --git a/debug/jupyter_notebook.ipynb b/debug/jupyter_notebook.ipynb
new file mode 100644
index 0000000..1db9e6d
--- /dev/null
+++ b/debug/jupyter_notebook.ipynb
@@ -0,0 +1,169 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Heading 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "MAX_VALUE = 20"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Heading 2\n",
+    "text\n",
+    "\n",
+    "- item 1.\n",
+    "    - item 1.1.\n",
+    "- item 2."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['Fizz',\n",
+       " '',\n",
+       " '',\n",
+       " 'Fizz',\n",
+       " '',\n",
+       " '',\n",
+       " 'Fizz',\n",
+       " '',\n",
+       " '',\n",
+       " 'Fizz',\n",
+       " '',\n",
+       " '',\n",
+       " 'Fizz',\n",
+       " '',\n",
+       " '',\n",
+       " 'Fizz',\n",
+       " '',\n",
+       " '',\n",
+       " 'Fizz',\n",
+       " '']"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Generate fizz list\n",
+    "fizz_list = [\"Fizz\" if i % 3 == 0 else \"\" for i in range(MAX_VALUE)]\n",
+    "\n",
+    "fizz_list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['Buzz',\n",
+       " '',\n",
+       " '',\n",
+       " '',\n",
+       " '',\n",
+       " 'Buzz',\n",
+       " '',\n",
+       " '',\n",
+       " '',\n",
+       " '',\n",
+       " 'Buzz',\n",
+       " '',\n",
+       " '',\n",
+       " '',\n",
+       " '',\n",
+       " 'Buzz',\n",
+       " '',\n",
+       " '',\n",
+       " '',\n",
+       " '']"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Generate buzz list\n",
+    "buzz_list = [\"Buzz\" if i % 5 == 0 else \"\" for i in range(MAX_VALUE)]\n",
+    "\n",
+    "buzz_list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[(0, 'FizzBizz'), (1, ''), (2, ''), (3, 'Fizz'), (4, ''), (5, 'Bizz'), (6, 'Fizz'), (7, ''), (8, ''), (9, 'Fizz'), (10, 'Bizz'), (11, ''), (12, 'Fizz'), (13, ''), (14, ''), (15, 'FizzBizz'), (16, ''), (17, ''), (18, 'Fizz'), (19, '')]\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Answer fizz buzz\n",
+    "answer = [fizz + buzz for fizz, buzz in zip(fizz_list, bizz_list)]\n",
+    "\n",
+    "print([(i, a) for i, a in enumerate(answer)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.8.5 64-bit",
+   "metadata": {
+    "interpreter": {
+     "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
+    }
+   },
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.10"
+  },
+  "orig_nbformat": 2
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/debug/long_table.csv b/debug/long_table.csv
new file mode 100644
index 0000000..c66136a
--- /dev/null
+++ b/debug/long_table.csv
@@ -0,0 +1,314 @@
+id, a, b
+0, 43, 43543
+1, 43, 5352
+2, 3432, 35
+3, 3432, 35
+4, 3432, 35
+5, 3432, 35
+6, 3432, 35
+7, 3432, 35
+8, 3432, 35
+9, 3432, 35
+10, 3432, 35
+11, 3432, 35
+12, 3432, 35
+13, 3432, 35
+14, 3432, 35
+15, 3432, 35
+16, 3432, 35
+17, 3432, 35
+18, 3432, 35
+19, 3432, 35
+20, 3432, 35
+21, 3432, 35
+22, 3432, 35
+23, 3432, 35
+24, 3432, 35
+25, 3432, 35
+26, 3432, 35
+27, 3432, 35
+28, 3432, 35
+29, 3432, 35
+30, 3432, 35
+31, 3432, 35
+32, 3432, 35
+33, 3432, 35
+34, 3432, 35
+35, 3432, 35
+36, 3432, 35
+37, 3432, 35
+38, 3432, 35
+39, 3432, 35
+40, 3432, 35
+41, 3432, 35
+42, 3432, 35
+43, 3432, 35
+44, 3432, 35
+45, 3432, 35
+46, 3432, 35
+47, 3432, 35
+48, 3432, 35
+49, 3432, 35
+50, 3432, 35
+51, 3432, 35
+52, 3432, 35
+53, 3432, 35
+54, 3432, 35
+55, 3432, 35
+56, 3432, 35
+57, 3432, 35
+58, 3432, 35
+59, 3432, 35
+60, 3432, 35
+61, 3432, 35
+62, 3432, 35
+63, 3432, 35
+64, 3432, 35
+65, 3432, 35
+66, 3432, 35
+67, 3432, 35
+68, 3432, 35
+69, 3432, 35
+70, 3432, 35
+71, 3432, 35
+72, 3432, 35
+73, 3432, 35
+74, 3432, 35
+75, 3432, 35
+76, 3432, 35
+77, 3432, 35
+78, 3432, 35
+79, 3432, 35
+80, 3432, 35
+81, 3432, 35
+82, 3432, 35
+83, 3432, 35
+84, 3432, 35
+85, 3432, 35
+86, 3432, 35
+87, 3432, 35
+88, 3432, 35
+89, 3432, 35
+90, 3432, 35
+91, 3432, 35
+92, 3432, 35
+93, 3432, 35
+94, 3432, 35
+95, 3432, 35
+96, 3432, 35
+97, 3432, 35
+98, 3432, 35
+99, 3432, 35
+100, 3432, 35
+101, 3432, 35
+102, 3432, 35
+103, 3432, 35
+104, 3432, 35
+105, 3432, 35
+106, 3432, 35
+107, 3432, 35
+108, 3432, 35
+109, 3432, 35
+110, 3432, 35
+111, 3432, 35
+112, 3432, 35
+113, 3432, 35
+114, 3432, 35
+115, 3432, 35
+116, 3432, 35
+117, 3432, 35
+118, 3432, 35
+119, 3432, 35
+120, 3432, 35
+121, 3432, 35
+122, 3432, 35
+123, 3432, 35
+124, 3432, 35
+125, 3432, 35
+126, 3432, 35
+127, 3432, 35
+128, 3432, 35
+129, 3432, 35
+130, 3432, 35
+131, 3432, 35
+132, 3432, 35
+133, 3432, 35
+134, 3432, 35
+135, 3432, 35
+136, 3432, 35
+137, 3432, 35
+138, 3432, 35
+139, 3432, 35
+140, 3432, 35
+141, 3432, 35
+142, 3432, 35
+143, 3432, 35
+144, 3432, 35
+145, 3432, 35
+146, 3432, 35
+147, 3432, 35
+148, 3432, 35
+149, 3432, 35
+150, 3432, 35
+151, 3432, 35
+152, 3432, 35
+153, 3432, 35
+154, 3432, 35
+155, 3432, 35
+156, 3432, 35
+157, 3432, 35
+158, 3432, 35
+159, 3432, 35
+160, 3432, 35
+161, 3432, 35
+162, 3432, 35
+163, 3432, 35
+164, 3432, 35
+165, 3432, 35
+166, 3432, 35
+167, 3432, 35
+168, 3432, 35
+169, 3432, 35
+170, 3432, 35
+171, 3432, 35
+172, 3432, 35
+173, 3432, 35
+174, 3432, 35
+175, 3432, 35
+176, 3432, 35
+177, 3432, 35
+178, 3432, 35
+179, 3432, 35
+180, 3432, 35
+181, 3432, 35
+182, 3432, 35
+183, 3432, 35
+184, 3432, 35
+185, 3432, 35
+186, 3432, 35
+187, 3432, 35
+188, 3432, 35
+189, 3432, 35
+190, 3432, 35
+191, 3432, 35
+192, 3432, 35
+193, 3432, 35
+194, 3432, 35
+195, 3432, 35
+196, 3432, 35
+197, 3432, 35
+198, 3432, 35
+199, 3432, 35
+200, 3432, 35
+201, 3432, 35
+202, 3432, 35
+203, 3432, 35
+204, 3432, 35
+205, 3432, 35
+206, 3432, 35
+207, 3432, 35
+208, 3432, 35
+209, 3432, 35
+210, 3432, 35
+211, 3432, 35
+212, 3432, 35
+213, 3432, 35
+214, 3432, 35
+215, 3432, 35
+216, 3432, 35
+217, 3432, 35
+218, 3432, 35
+219, 3432, 35
+220, 3432, 35
+221, 3432, 35
+222, 3432, 35
+223, 3432, 35
+224, 3432, 35
+225, 3432, 35
+226, 3432, 35
+227, 3432, 35
+228, 3432, 35
+229, 3432, 35
+230, 3432, 35
+231, 3432, 35
+232, 3432, 35
+233, 3432, 35
+234, 3432, 35
+235, 3432, 35
+236, 3432, 35
+237, 3432, 35
+238, 3432, 35
+239, 3432, 35
+240, 3432, 35
+241, 3432, 35
+242, 3432, 35
+243, 3432, 35
+244, 3432, 35
+245, 3432, 35
+246, 3432, 35
+247, 3432, 35
+248, 3432, 35
+249, 3432, 35
+250, 3432, 35
+251, 3432, 35
+252, 3432, 35
+253, 3432, 35
+254, 3432, 35
+255, 3432, 35
+256, 3432, 35
+257, 3432, 35
+258, 3432, 35
+259, 3432, 35
+260, 3432, 35
+261, 3432, 35
+262, 3432, 35
+263, 3432, 35
+264, 3432, 35
+265, 3432, 35
+266, 3432, 35
+267, 3432, 35
+268, 3432, 35
+269, 3432, 35
+270, 3432, 35
+271, 3432, 35
+272, 3432, 35
+273, 3432, 35
+274, 3432, 35
+275, 3432, 35
+276, 3432, 35
+277, 3432, 35
+278, 3432, 35
+279, 3432, 35
+280, 3432, 35
+281, 3432, 35
+282, 3432, 35
+283, 3432, 35
+284, 3432, 35
+285, 3432, 35
+286, 3432, 35
+287, 3432, 35
+288, 3432, 35
+289, 3432, 35
+290, 3432, 35
+291, 3432, 35
+292, 3432, 35
+293, 3432, 35
+294, 3432, 35
+295, 3432, 35
+296, 3432, 35
+297, 3432, 35
+298, 3432, 35
+299, 3432, 35
+300, 3432, 35
+301, 3432, 35
+302, 3432, 35
+303, 3432, 35
+304, 3432, 35
+305, 3432, 35
+306, 3432, 35
+307, 3432, 35
+308, 3432, 35
+309, 3432, 35
+310, 3432, 35
+311, 3432, 35
+
diff --git a/debug/many-columns-table.csv b/debug/many-columns-table.csv
new file mode 100644
index 0000000..fb8476c
--- /dev/null
+++ b/debug/many-columns-table.csv
@@ -0,0 +1,16 @@
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10000000000,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
+1,2,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,8,9,10,1,2,3,4
diff --git a/debug/markdown.md b/debug/markdown.md
new file mode 100644
index 0000000..dac1b27
--- /dev/null
+++ b/debug/markdown.md
@@ -0,0 +1,43 @@
+# heading1 {#p2}
+heading1本文一行目
+
+## heading2 
+heading2本文
+
+##### heading5
+heading5本文  
+Here is a footnote reference,[^1] and another.[^longnote]
+
+[^1]: 脚注その1
+
+[^longnote]: これは脚注その2に割り振られます
+
+######### heading8
+heading8本文。  
+
+######### heading9
+heading9本文。  
+
++---------------+---------------+--------------------+
+| 名称          | 金額          | Advantages          |
++:=============:+==============:+:===================+
+| お茶          | 2000円        | - 名産品            |
+|               |               | - 新茶             |
++---------------+---------------+--------------------+
+| お水          | 130円         | - 天然水            |
++---------------+---------------+--------------------+
+
+[heading1へのリンク確認](#p2)  
+
+* 記号*か+か-を先頭につける。テキストとの間にはスペース
+* 記号*か+か-を先頭につける。テキストとの間にはスペース
+    + インデントさせる場合は4つスペース
+        + さらにインデントさせる場合は8つスペース
+
+
+1. 数字,ピリオド,スペースで順序付きリスト
+1. 数字,ピリオド,スペースで順序付きリスト
+
+画像も。
+
+![テストイメージ](test.bmp)
\ No newline at end of file
diff --git a/debug/permission.txt b/debug/permission.txt
new file mode 100644
index 0000000..e69de29
diff --git a/debug/python.py b/debug/python.py
new file mode 100644
index 0000000..299ebb1
--- /dev/null
+++ b/debug/python.py
@@ -0,0 +1,56 @@
+from rich.console import Console
+from rich.markdown import Markdown
+from rich.syntax import Syntax
+from rich.panel import Panel
+from rich.console import RenderGroup
+
+console = Console()
+
+text1 = """
+import numpy as np
+a = np.array([1,2,3,4,5])
+a
+"""
+text1 = Panel(Syntax(text1, 'python', line_numbers=True))
+
+
+text2 = """
+```
+array([1, 2, 3, 4, 5])
+```
+"""
+text2 = Markdown(text2)
+
+
+text3 = """
+b
+"""
+text3 = Panel(Syntax(text3, 'python', line_numbers=True))
+
+
+text4 = """
+---------------------------------------------------------------------------
+NameError                                 Traceback (most recent call last)
+<ipython-input-2-89e6c98d9288> in <module>
+----> 1 b
+
+NameError: name 'b' is not defined
+"""
+#  text4 = Markdown(text4)
+text4 = Panel(Syntax(text4, 'python', line_numbers=True))
+
+code1 = RenderGroup(
+        "code:[1]",
+        text1,
+        "output:[1]",
+        text2
+        )
+console.print(Panel(code1))
+print()
+code2 = RenderGroup(
+        "code:[2]",
+        text3,
+        "output:[2]",
+        text4
+        )
+console.print(Panel(code2))
diff --git a/debug/richcat_on_nb.ipynb b/debug/richcat_on_nb.ipynb
new file mode 100644
index 0000000..285171c
--- /dev/null
+++ b/debug/richcat_on_nb.ipynb
@@ -0,0 +1,108 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from richcat import richcat"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m1 \u001b[0m\u001b[38;5;117;48;5;235mvar\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;149;48;5;235mx\u001b[0m\u001b[38;5;231;48;5;235m,\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;149;48;5;235my\u001b[0m\u001b[38;5;231;48;5;235m,\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;149;48;5;235mz\u001b[0m\u001b[38;5;231;48;5;235m;\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;102;48;5;235m// Declare 3 variables\u001b[0m\u001b[48;5;235m                                         \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m2 \u001b[0m\u001b[38;5;149;48;5;235mx\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;204;48;5;235m=\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;147;48;5;235m5\u001b[0m\u001b[38;5;231;48;5;235m;\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;102;48;5;235m// Assign the value 5 to x\u001b[0m\u001b[48;5;235m                                           \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m3 \u001b[0m\u001b[38;5;149;48;5;235my\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;204;48;5;235m=\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;147;48;5;235m6\u001b[0m\u001b[38;5;231;48;5;235m;\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;102;48;5;235m// Assign the value 6 to y\u001b[0m\u001b[48;5;235m                                           \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m4 \u001b[0m\u001b[38;5;149;48;5;235mz\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;204;48;5;235m=\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;149;48;5;235mx\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;204;48;5;235m+\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;149;48;5;235my\u001b[0m\u001b[38;5;231;48;5;235m;\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;102;48;5;235m// Assign the sum of x and y to z\u001b[0m\u001b[48;5;235m                                \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m5 \u001b[0m\u001b[48;5;235m                                                                            \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m6 \u001b[0m\u001b[38;5;231;48;5;235mdocument\u001b[0m\u001b[38;5;231;48;5;235m.\u001b[0m\u001b[38;5;149;48;5;235mgetElementById\u001b[0m\u001b[38;5;231;48;5;235m(\u001b[0m\u001b[38;5;222;48;5;235m\"demo\"\u001b[0m\u001b[38;5;231;48;5;235m)\u001b[0m\u001b[38;5;231;48;5;235m.\u001b[0m\u001b[38;5;149;48;5;235minnerHTML\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;204;48;5;235m=\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;222;48;5;235m\"The value of z is \"\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;204;48;5;235m+\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;149;48;5;235mz\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;204;48;5;235m+\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;222;48;5;235m\".\"\u001b[0m\u001b[38;5;231;48;5;235m;\u001b[0m\u001b[48;5;235m \u001b[0m\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "richcat(\"./javascript.js\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m1 \u001b[0m\u001b[38;5;204;48;5;235mimport\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;231;48;5;235mnumpy\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;117;48;5;235mas\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;231;48;5;235mnp\u001b[0m\u001b[48;5;235m     \u001b[0m\n",
+      "\u001b[1;38;5;253;48;5;235m  \u001b[0m\u001b[38;5;241;48;5;235m2 \u001b[0m\u001b[38;5;231;48;5;235mnp\u001b[0m\u001b[38;5;204;48;5;235m.\u001b[0m\u001b[38;5;231;48;5;235marray\u001b[0m\u001b[38;5;231;48;5;235m(\u001b[0m\u001b[38;5;231;48;5;235m[\u001b[0m\u001b[38;5;147;48;5;235m1\u001b[0m\u001b[38;5;231;48;5;235m,\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;147;48;5;235m2\u001b[0m\u001b[38;5;231;48;5;235m,\u001b[0m\u001b[38;5;231;48;5;235m \u001b[0m\u001b[38;5;147;48;5;235m3\u001b[0m\u001b[38;5;231;48;5;235m]\u001b[0m\u001b[38;5;231;48;5;235m)\u001b[0m\u001b[48;5;235m    \u001b[0m\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "richcat(\n",
+    "    file_contents=\"\"\"import numpy as np\n",
+    "np.array([1, 2, 3])\"\"\",\n",
+    "    filetype=\"python\"\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "interpreter": {
+   "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
+  },
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/debug/sample.md b/debug/sample.md
new file mode 100644
index 0000000..29b8678
--- /dev/null
+++ b/debug/sample.md
@@ -0,0 +1,37 @@
+# header 1
+## header 2
+### header 3
+#### header 4
+##### header 5
+###### header 6
+
+- list
+    - abc
+    - def
+        - ghi
+        - jkl
+
+1. numerical list
+1. numerical list
+
+```
+import numpy as np
+print(np.array([1,2,3,4]))
+```
+
+aaaaaaaaa
+
+```python
+import numpy as np
+print(np.array([1,2,3,4]))
+```
+
+
+# table
+| aaa | bbb | ccc |
+| --- | --- | --- |
+| bbb | 344 | 535 |
+| bbb | 344 | 535 |
+| bbb | 344 | 535 |
+| bbb | 344 | 535 |
+| bbb | 344 | 535 |
diff --git a/debug/table.csv b/debug/table.csv
new file mode 100644
index 0000000..28a1f84
--- /dev/null
+++ b/debug/table.csv
@@ -0,0 +1,11 @@
+id, a, b
+0, 43, 43543
+1, 43, 5352
+2, 3432, 35
+3, 3432, 35
+4, 3432, 35
+5, 3432, 35
+6, 3432, 35
+7, 3432, 35
+8, 3432, 35
+
diff --git a/debug/text.txt b/debug/text.txt
new file mode 100644
index 0000000..124ffc0
--- /dev/null
+++ b/debug/text.txt
@@ -0,0 +1,3 @@
+sample text 01
+sample text 02
+sample text 03
diff --git a/debug/too-long-text.py b/debug/too-long-text.py
new file mode 100644
index 0000000..1ff20a1
--- /dev/null
+++ b/debug/too-long-text.py
@@ -0,0 +1,1 @@
+a = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
diff --git a/debug/wide-table.csv b/debug/wide-table.csv
new file mode 100644
index 0000000..646b6e1
--- /dev/null
+++ b/debug/wide-table.csv
@@ -0,0 +1,2 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,cccccccccccccccccccccccccccccccccccc
+0,1,2
diff --git a/doc/img/index-html.jpg b/doc/img/index-html.jpg
deleted file mode 100644
index ffefcab..0000000
Binary files a/doc/img/index-html.jpg and /dev/null differ
diff --git a/doc/img/sample-md.jpg b/doc/img/sample-md.jpg
deleted file mode 100644
index e3cb63e..0000000
Binary files a/doc/img/sample-md.jpg and /dev/null differ
diff --git a/doc/img/table-csv.jpg b/doc/img/table-csv.jpg
deleted file mode 100644
index eeef0a0..0000000
Binary files a/doc/img/table-csv.jpg and /dev/null differ
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..94b215c
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,31 @@
+version: '3'
+
+services:
+  richcat-dev:
+    build: .
+    image: richcat-dev
+    container_name: richcat-dev
+    ports:
+      - 8000:8000 # For Sphinx
+      - 8888:8888 # For Jupyter
+    volumes:
+      - type: bind
+        source: "./"
+        target: "/home/"
+      - type: bind
+        source: "/var/run/docker.sock"
+        target: "/var/run/docker.sock"
+    command: bash -c "pip install -e /home && make apidoc && make autobuild"
+    tty: true
+  richcat-play:
+    build: ./richcat-play-env
+    image: richcat-play
+    container_name: richcat-play
+    volumes:
+      - type: bind
+        source: "./richcat-play-env/"
+        target: "/home/"
+      - type: bind
+        source: "./debug"
+        target: "/home/debug"
+    tty: true
diff --git a/requirements.txt b/requirements.txt
index 3f382dd..5a4c7b6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,1 +1,10 @@
-rich
+# Base libraries
+rich == 11.1.0
+
+# For Sphinx
+sphinx == 4.4.0
+sphinx-autobuild == 2021.3.14
+sphinx_rtd_theme == 1.0.0
+
+# Testing
+pytest == 6.2.5
\ No newline at end of file
diff --git a/richcat-play-env/.bashrc b/richcat-play-env/.bashrc
new file mode 100644
index 0000000..bf55572
--- /dev/null
+++ b/richcat-play-env/.bashrc
@@ -0,0 +1,10 @@
+# Colorize prompt
+export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
+
+# Set less command options
+export LESS="-F -g -i -M -R -S -w -X -z-4"
+
+alias install-richcat='_install_richcat'
+function _install_richcat() {
+    \pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ richcat==$@
+}
diff --git a/richcat-play-env/Dockerfile b/richcat-play-env/Dockerfile
new file mode 100644
index 0000000..86a2f65
--- /dev/null
+++ b/richcat-play-env/Dockerfile
@@ -0,0 +1,15 @@
+# Base image
+FROM python:3.7
+
+# Environment
+ENV HOME /home
+WORKDIR $HOME
+COPY .bashrc $HOME/
+
+# Installl commands
+RUN apt-get update && apt-get upgrade -y \
+    && apt-get install -y \
+    less
+
+# Install Python libraries
+RUN pip install --upgrade pip
\ No newline at end of file
diff --git a/richcat/__information__.py b/richcat/__information__.py
index e24e6ad..e6df5ab 100644
--- a/richcat/__information__.py
+++ b/richcat/__information__.py
@@ -1,6 +1,6 @@
-__copyright__    = 'Copyright (C) 2020 Yuta Yamamoto, Shotaro Kataoka'
-__version__      = '0.4.1'
-__license__      = 'MIT'
-__author__       = 'Yuta Yamamoto, Shotaro Kataoka'
+__copyright__ = 'Copyright (C) 2020 Yuta Yamamoto, Shotaro Kataoka'
+__version__ = '0.5.0'
+__license__ = 'MIT'
+__author__ = 'Yuta Yamamoto, Shotaro Kataoka'
 __author_email__ = 'automatuX78@gmail.com'
-__url__          = 'https://github.com/richcat-dev/richcat'
+__url__ = 'https://github.com/richcat-dev/richcat'
diff --git a/richcat/__init__.py b/richcat/__init__.py
index 785217c..1276060 100644
--- a/richcat/__init__.py
+++ b/richcat/__init__.py
@@ -1,8 +1,18 @@
+from . import richcat as rc
 from .richcat import richcat as exec_richcat
 from .modules.consts._const import DIC_DEFAULT_VALUES
 from .__information__ import __copyright__, __version__, __license__, __author__, __author_email__, __url__
 
 
+__copyright__ = __copyright__
+__version__ = __version__
+__license__ = __license__
+__author__ = __author__
+__author_email__ = __author_email__
+__url__ = __url__
+rc = rc
+
+
 def richcat(filepath=None, file_contents=None, **args):
     """
     The richcat function called from Python script
@@ -22,12 +32,13 @@ def richcat(filepath=None, file_contents=None, **args):
     -------
 
     """
-    
+
     if ((filepath is None) and (file_contents is None)):
         file_contents = 'Please input `filepath` or `file_contents`.'
         args['filetype'] = 'md'
     if filepath is not None:
         file_contents = None
+
     class Args():
         def __init__(self):
             self.filepath = filepath
@@ -43,4 +54,3 @@ def __init__(self):
     args = Args()
 
     exec_richcat(args)
-
diff --git a/richcat/modules/__init__.py b/richcat/modules/__init__.py
index e69de29..83230b8 100644
--- a/richcat/modules/__init__.py
+++ b/richcat/modules/__init__.py
@@ -0,0 +1,4 @@
+"""
+This is richcat/modules module.
+This has most of basic functions of richcat.
+"""
diff --git a/richcat/modules/consts/_ext2alias_dic_generator.py b/richcat/modules/consts/_ext2alias_dic_generator.py
index d4edce0..ce19ce6 100644
--- a/richcat/modules/consts/_ext2alias_dic_generator.py
+++ b/richcat/modules/consts/_ext2alias_dic_generator.py
@@ -1,22 +1,23 @@
 """
 richcat.modules._ext2alias_dic_generator
 ----------------------------------------
-Dictionary for convert extension to alias. 
+Dictionary for convert extension to alias.
 This file is generated by itself. Every Time you change something on this dictionary, run this script to update it.
 """
 
-import os
-import pickle
-import subprocess
-
 from pygments.lexers import get_all_lexers
 
 DIC_LEXER_WC = {
-    'abap': 'abap',
-    'ABAP': 'abap',
+    'isa': 'amdgpu',
     'apl': 'apl',
+    'aplf': 'apl',
+    'aplo': 'apl',
+    'apln': 'apl',
+    'aplc': 'apl',
+    'apli': 'apl',
+    'dyalog': 'apl',
     'abnf': 'abnf',
-    'as': 'as',
+    'as': 'actionscript',
     'adb': 'ada',
     'ads': 'ada',
     'ada': 'ada',
@@ -27,23 +28,27 @@
     'agda': 'agda',
     'aheui': 'aheui',
     'als': 'alloy',
-    'at': 'at',
+    'at': 'ambienttalk',
     'run': 'ampl',
     'ng2': 'html+ng2',
     'G': 'antlr-ruby',
     'g': 'gap',
     'applescript': 'applescript',
     'ino': 'arduino',
+    'arw': 'arrow',
+    'asc': 'asc',
+    'pem': 'asc',
     'aj': 'aspectj',
-    'asy': 'asy',
+    'asy': 'asymptote',
     'aug': 'augeas',
     'au3': 'autoit',
-    'ahk': 'ahk',
-    'ahkl': 'ahk',
+    'ahk': 'autohotkey',
+    'ahkl': 'autohotkey',
     'awk': 'awk',
     'bbc': 'bbcbasic',
     'bc': 'bc',
     'bst': 'bst',
+    'bare': 'bare',
     'sh': 'bash',
     'ksh': 'bash',
     'bash': 'bash',
@@ -54,10 +59,11 @@
     'zsh': 'bash',
     'sh-session': 'console',
     'shell-session': 'console',
-    'bat': 'bat',
-    'cmd': 'bat',
+    'bat': 'batch',
+    'cmd': 'batch',
+    'feature': 'gherkin',
     'befunge': 'befunge',
-    'bib': 'bib',
+    'bib': 'bibtex',
     'bb': 'blitzbasic',
     'decls': 'blitzbasic',
     'bmx': 'blitzmax',
@@ -73,6 +79,7 @@
     'c': 'c',
     'h': 'objective-c',
     'idc': 'c',
+    'x[bp]m': 'c',
     'cmake': 'cmake',
     'c-objdump': 'c-objdump',
     'cpsa': 'cpsa',
@@ -88,9 +95,10 @@
     'cdl': 'capdl',
     'capnp': 'capnp',
     'bas': 'vb.net',
+    'cddl': 'cddl',
     'ceylon': 'ceylon',
     'cf': 'cfengine3',
-    'chai': 'chai',
+    'chai': 'chaiscript',
     'chpl': 'chapel',
     'ci': 'charmci',
     'tmpl': 'cheetah',
@@ -107,7 +115,7 @@
     'COB': 'cobol',
     'cpy': 'cobol',
     'CPY': 'cobol',
-    'coffee': 'coffee-script',
+    'coffee': 'coffeescript',
     'cfc': 'cfc',
     'cfm': 'cfm',
     'cfml': 'cfm',
@@ -157,6 +165,8 @@
     'dasm': 'dasm16',
     'pas': 'delphi',
     'dpr': 'delphi',
+    'dts': 'devicetree',
+    'dtsi': 'devicetree',
     'dg': 'dg',
     'diff': 'diff',
     'patch': 'diff',
@@ -175,14 +185,16 @@
     'eh': 'ec',
     'eg': 'earl-grey',
     'ezt': 'easytrieve',
-    'mac': 'easytrieve',
+    'mac': 'maxima',
     'ebnf': 'ebnf',
     'e': 'eiffel',
     'ex': 'elixir',
     'eex': 'elixir',
     'exs': 'elixir',
+    'leex': 'elixir',
     'elm': 'elm',
-    'el': 'emacs',
+    'elpi': 'elpi',
+    'el': 'emacs-lisp',
     'eml': 'email',
     'erl': 'erlang',
     'hrl': 'erlang',
@@ -192,9 +204,12 @@
     'html': 'html',
     'evoque': 'evoque',
     'xml': 'xml',
+    'exec': 'execline',
     'n': 'nemerle',
     'fs': 'forth',
     'fsi': 'fsharp',
+    'fst': 'fstar',
+    'fsti': 'fstar',
     'factor': 'factor',
     'fy': 'fancy',
     'fancypack': 'fancy',
@@ -215,17 +230,19 @@
     'PRG': 'foxpro',
     'prg': 'foxpro',
     'edp': 'freefem',
-    'gd': 'gap',
+    'fut': 'futhark',
+    'gd': 'gdscript',
     'gi': 'gap',
     'gap': 'gap',
     'vert': 'glsl',
     'frag': 'glsl',
     'geo': 'glsl',
+    'gsql': 'gsql',
     'S': 'splus',
+    'gcode': 'gcode',
     'kid': 'genshi',
     'pot': 'pot',
     'po': 'pot',
-    'feature': 'cucumber',
     'plot': 'gnuplot',
     'plt': 'gnuplot',
     'go': 'go',
@@ -236,8 +253,12 @@
     'gsp': 'gosu',
     'vark': 'gosu',
     'gst': 'gst',
-    '[1234567]': 'groff',
+    'gv': 'graphviz',
+    'dot': 'graphviz',
+    '[1-9]': 'groff',
     'man': 'groff',
+    '1p': 'groff',
+    '3pm': 'groff',
     'groovy': 'groovy',
     'gradle': 'groovy',
     'hlsl': 'hlsl',
@@ -246,8 +267,8 @@
     'handlebars': 'html+handlebars',
     'hbs': 'html+handlebars',
     'hs': 'haskell',
-    'hx': 'hx',
-    'hxsl': 'hx',
+    'hx': 'haxe',
+    'hxsl': 'haxe',
     'hsail': 'hsail',
     'htm': 'html',
     'xhtml': 'html',
@@ -267,17 +288,30 @@
     'i7x': 'inform7',
     'ini': 'ini',
     'cfg': 'ini',
+    'service': 'ini',
+    'socket': 'ini',
+    'device': 'ini',
+    'mount': 'ini',
+    'automount': 'ini',
+    'swap': 'ini',
+    'target': 'ini',
+    'path': 'ini',
+    'timer': 'ini',
+    'slice': 'ini',
+    'scope': 'ini',
     'io': 'io',
     'ik': 'ioke',
     'weechatlog': 'irc',
     'thy': 'isabelle',
     'ijs': 'j',
+    'jslt': 'jslt',
     'jag': 'jags',
     'j': 'objective-j',
     'java': 'java',
-    'js': 'js',
-    'jsm': 'js',
-    'mjs': 'js',
+    'js': 'javascript',
+    'jsm': 'javascript',
+    'mjs': 'javascript',
+    'cjs': 'javascript',
     'jcl': 'jcl',
     'jsgf': 'jsgf',
     'jsonld': 'jsonld',
@@ -291,17 +325,20 @@
     'kk': 'koka',
     'kki': 'koka',
     'kt': 'kotlin',
+    'kts': 'kotlin',
+    'kn': 'kuin',
     'lsl': 'lsl',
     'lasso': 'lasso',
     'lasso[89]': 'lasso',
     'lean': 'lean',
     'less': 'less',
+    'ly': 'lilypond',
     'liquid': 'liquid',
-    'lagda': 'lagda',
-    'lcry': 'lcry',
-    'lhs': 'lhs',
-    'lidr': 'lidr',
-    'ls': 'live-script',
+    'lagda': 'literate-agda',
+    'lcry': 'literate-cryptol',
+    'lhs': 'literate-haskell',
+    'lidr': 'literate-idris',
+    'ls': 'livescript',
     'll': 'llvm',
     'mir': 'llvm-mir',
     'x': 'logos',
@@ -317,7 +354,8 @@
     'mk': 'make',
     'mao': 'mako',
     'maql': 'maql',
-    'md': 'md',
+    'md': 'markdown',
+    'markdown': 'markdown',
     'mask': 'mask',
     'm': 'octave',
     'mhtml': 'mason',
@@ -327,13 +365,14 @@
     'cdf': 'mathematica',
     'nbp': 'mathematica',
     'ma': 'mathematica',
-    'ms': 'ms',
+    'max': 'maxima',
+    'ms': 'miniscript',
     'mo': 'modelica',
-    'def': 'modula2',
+    'def': 'singularity',
     'mod': 'modula2',
     'monkey': 'monkey',
     'mt': 'monte',
-    'moon': 'moon',
+    'moon': 'moonscript',
     'mos': 'mosel',
     'css.in': 'css+mozpreproc',
     'js.in': 'javascript+mozpreproc',
@@ -352,12 +391,13 @@
     'ASM': 'tasm',
     'objdump-intel': 'objdump-nasm',
     'nc': 'nesc',
+    'nt': 'nestedtext',
     'lsp': 'newlisp',
     'nl': 'newlisp',
     'kif': 'newlisp',
     'ns2': 'newspeak',
-    'nim': 'nim',
-    'nimrod': 'nim',
+    'nim': 'nimrod',
+    'nimrod': 'nimrod',
     'nit': 'nit',
     'nix': 'nixos',
     'smv': 'nusmv',
@@ -368,6 +408,8 @@
     'mll': 'ocaml',
     'mly': 'ocaml',
     'odin': 'odin',
+    'idl': 'omg-idl',
+    'pidl': 'omg-idl',
     'ooc': 'ooc',
     'opa': 'opa',
     'p': 'pawn',
@@ -393,12 +435,14 @@
     'rakumod': 'perl6',
     'rakutest': 'perl6',
     'rakudoc': 'perl6',
+    'perl': 'perl',
     'php': 'php',
     'php[345]': 'php',
     'pig': 'pig',
     'pike': 'pike',
     'pmod': 'pike',
     'pc': 'pkgconfig',
+    'ptls': 'pointless',
     'pony': 'pony',
     'ps': 'postscript',
     'eps': 'postscript',
@@ -409,6 +453,7 @@
     'proc': 'praat',
     'psc': 'praat',
     'prolog': 'prolog',
+    'promql': 'promql',
     'properties': 'properties',
     'proto': 'protobuf',
     'pug': 'pug',
@@ -420,7 +465,7 @@
     'pyw': 'python',
     'jy': 'python',
     'sage': 'python',
-    'sc': 'sc',
+    'sc': 'supercollider',
     'bzl': 'python',
     'tac': 'python',
     'pytb': 'pytb',
@@ -430,15 +475,15 @@
     'qml': 'qml',
     'qbs': 'qml',
     'Rout': 'rconsole',
-    'rnc': 'rnc',
+    'rnc': 'rng-compact',
     'spec': 'spec',
     'rkt': 'racket',
     'rktd': 'racket',
     'rktl': 'racket',
     'rl': 'ragel-ruby',
     'Rd': 'rd',
-    're': 'reason',
-    'rei': 'reason',
+    're': 'reasonml',
+    'rei': 'reasonml',
     'r': 'rebol',
     'r3': 'rebol',
     'reb': 'rebol',
@@ -452,20 +497,21 @@
     'arexx': 'rexx',
     'rhtml': 'rhtml',
     'ride': 'ride',
+    'rita': 'rita',
     'graph': 'roboconf-graph',
     'instances': 'roboconf-instances',
     'robot': 'robotframework',
     'rql': 'rql',
     'rsl': 'rsl',
-    'rst': 'rst',
-    'rest': 'rst',
-    'rts': 'rts',
-    'rb': 'rb',
-    'rbw': 'rb',
-    'rake': 'rb',
-    'gemspec': 'rb',
-    'rbx': 'rb',
-    'duby': 'rb',
+    'rst': 'restructuredtext',
+    'rest': 'restructuredtext',
+    'rts': 'trafficscript',
+    'rb': 'ruby',
+    'rbw': 'ruby',
+    'rake': 'ruby',
+    'gemspec': 'ruby',
+    'rbx': 'ruby',
+    'duby': 'ruby',
     'rs': 'rust',
     'rs.in': 'rust',
     'SAS': 'sas',
@@ -476,9 +522,10 @@
     'fun': 'sml',
     'sarl': 'sarl',
     'sass': 'sass',
+    'savi': 'savi',
     'scala': 'scala',
     'scaml': 'scaml',
-    'scd': 'sc',
+    'scd': 'supercollider',
     'scdoc': 'scdoc',
     'scm': 'scheme',
     'ss': 'scheme',
@@ -486,24 +533,30 @@
     'sce': 'scilab',
     'tst': 'scilab',
     'scss': 'scss',
+    'sed': 'sed',
+    '[gs]sed': 'sed',
     'shex': 'shexc',
     'shen': 'shen',
     'siv': 'sieve',
     'sieve': 'sieve',
     'sil': 'silver',
     'vpr': 'silver',
-    'sl': 'slurm',
+    'sla': 'slash',
     'slim': 'slim',
+    'sl': 'slurm',
     'smali': 'smali',
     'st': 'smalltalk',
     'sgf': 'sgf',
     'tpl': 'smarty',
+    'smithy': 'smithy',
     'snobol': 'snobol',
     'sbl': 'snowball',
     'sol': 'solidity',
+    'aes': 'sophia',
     'sp': 'sp',
     'rq': 'sparql',
     'sparql': 'sparql',
+    'spice': 'spice',
     'sql': 'tsql',
     'sqlite3-console': 'sqlite3',
     'ssp': 'ssp',
@@ -516,6 +569,7 @@
     'sv': 'systemverilog',
     'svh': 'systemverilog',
     'tap': 'tap',
+    'tnt': 'tnt',
     'toml': 'toml',
     'tasm': 'tasm',
     'tcl': 'tcl',
@@ -523,19 +577,21 @@
     'tcsh': 'tcsh',
     'csh': 'tcsh',
     'tea': 'tea',
+    'teal': 'teal',
     'ttl': 'turtle',
     'tf': 'terraform',
     'tex': 'tex',
     'aux': 'tex',
     'toc': 'tex',
     'txt': 'text',
+    'ti': 'ti',
     'thrift': 'thrift',
+    'tid': 'tid',
     'todotxt': 'todotxt',
     'treetop': 'treetop',
     'tt': 'treetop',
     'twig': 'html+twig',
-    'ts': 'ts',
-    'tsx': 'ts',
+    'ts': 'typescript',
     'typoscript': 'typoscript',
     'u': 'urbiscript',
     'u1': 'ucode',
@@ -556,6 +612,8 @@
     'vhd': 'vhdl',
     'vim': 'vim',
     'wdiff': 'wdiff',
+    'wat': 'wast',
+    'wast': 'wast',
     'webidl': 'webidl',
     'whiley': 'whiley',
     'x10': 'x10',
@@ -575,53 +633,71 @@
     'sls': 'yaml+jinja',
     'yaml': 'yaml',
     'yml': 'yaml',
+    'yang': 'yang',
     'zeek': 'zeek',
     'bro': 'zeek',
     'zep': 'zephir',
     'zig': 'zig',
+    'ans': 'ansys',
 }
 
 DIC_LEXER_CONST = {
     '.htaccess': 'apacheconf',
     'apache.conf': 'apacheconf',
     'apache2.conf': 'apacheconf',
+    'id_dsa': 'asc',
+    'id_ecdsa': 'asc',
+    'id_ecdsa_sk': 'asc',
+    'id_ed25519': 'asc',
+    'id_ed25519_sk': 'asc',
+    'id_rsa': 'asc',
     '.bashrc': 'bash',
     'bashrc': 'bash',
     '.bash_*': 'bash',
     'bash_*': 'bash',
     'zshrc': 'bash',
     '.zshrc': 'bash',
+    '.kshrc': 'bash',
+    'kshrc': 'bash',
     'PKGBUILD': 'bash',
     'CMakeLists.txt': 'cmake',
-    'control': 'control',
+    'control': 'debcontrol',
     'Dockerfile': 'docker',
+    '.editorconfig': 'ini',
     'Pipfile.lock': 'json',
-    'Kconfig': 'kconfig',
+    'Kconfig*': 'kconfig',
     '*Config.in*': 'kconfig',
     'external.in*': 'kconfig',
     'standard-modules.in': 'kconfig',
+    'lighttpd.conf': 'lighttpd',
     'Makefile': 'make',
     'makefile': 'make',
     'Makefile.*': 'make',
     'GNUmakefile': 'make',
     'autohandler': 'mason',
     'dhandler': 'mason',
+    'meson.build': 'meson',
+    'meson_options.txt': 'meson',
     'autodelegate': 'myghty',
     'nginx.conf': 'nginx',
     'pacman.conf': 'pacmanconf',
+    'Procfile': 'procfile',
     'SConstruct': 'python',
     'SConscript': 'python',
     'BUCK': 'python',
     'BUILD': 'python',
     'BUILD.bazel': 'python',
     'WORKSPACE': 'python',
-    'Rakefile': 'rb',
-    'Gemfile': 'rb',
+    'Rakefile': 'ruby',
+    'Gemfile': 'ruby',
+    'Vagrantfile': 'ruby',
     '.Rhistory': 'splus',
     '.Rprofile': 'splus',
     '.Renviron': 'splus',
-    'sources.list': 'sourceslist',
+    'Singularity': 'singularity',
+    'sources.list': 'debsources',
     'squid.conf': 'squidconf',
+    '.SRCINFO': 'srcinfo',
     'Pipfile': 'toml',
     'poetry.lock': 'toml',
     'termcap': 'termcap',
diff --git a/richcat/modules/exceptions/exception.py b/richcat/modules/exceptions/exception.py
index af9d9fd..a14d9b3 100644
--- a/richcat/modules/exceptions/exception.py
+++ b/richcat/modules/exceptions/exception.py
@@ -1,6 +1,4 @@
-"""
-Exception error classes
-"""
+"""Exception error classes."""
 
 from abc import abstractmethod
 
@@ -8,16 +6,17 @@
 
 
 class AbstractRichcatError(Exception):
-    """ Abstract richcat error class """
 
-    """ Class variables """
+    """Abstract richcat error class"""
+
+    # Class variables
     ERROR_HEAD = r'[bold red]\[richcat error][/bold red]:'
     console = Console()
 
     def exec_print(self, error_msg):
         """
         Method execute print process
-        
+
         Parameters
         ----------
         error_msg : str
@@ -27,12 +26,11 @@ def exec_print(self, error_msg):
 
     @abstractmethod
     def print_error(self):
-        """ Method print error (For child classes) """
         pass
 
 
 class RichcatFileNotFoundError(AbstractRichcatError):
-    """ 
+    """
     FileNotFoundError class
     Raise : If input failed because the path does not exist.
     """
@@ -53,7 +51,7 @@ def print_error(self):
 
 
 class RichcatIsDirectoryError(AbstractRichcatError):
-    """ 
+    """
     IsDirectory class
     Raise : If input failed because it is a directory.
     """
@@ -74,7 +72,7 @@ def print_error(self):
 
 
 class RichcatPermissionError(AbstractRichcatError):
-    """ 
+    """
     PermissionError class
     Raise : If input failed because of permission denied.
     """
@@ -95,7 +93,7 @@ def print_error(self):
 
 
 class RichcatTerminalWidthGetError(AbstractRichcatError):
-    """ 
+    """
     TerminalWidthGetError class
     Raise : If 'stty' failed.
     """
@@ -103,9 +101,10 @@ def print_error(self):
         self.exec_print('Cloud not get terminal width. Please give terminal width by using "width" option.')
 
 class RichcatBrokenPipeError(AbstractRichcatError):
-    """ 
+    """
     RichcatBrokenPipeError class
     Raise : If pipe is broken.
     """
     def print_error(self):
         pass
+
diff --git a/richcat/modules/help.py b/richcat/modules/help.py
index 3795ba2..58b2b23 100644
--- a/richcat/modules/help.py
+++ b/richcat/modules/help.py
@@ -1,5 +1,6 @@
 from ..__information__ import __version__
 
+
 def print_help():
     return f"# richcat {__version__}"+"""
 The `richcat` command supporting various types of files.
@@ -7,7 +8,6 @@ def print_help():
 ## USAGE
 ```js
 richcat <OPTIONS> <FILE>
-<COMMANDS> | richcat -w <INT> <OPTIONS>
 ```
 
 ## ARGS
@@ -28,7 +28,7 @@ def print_help():
                             | 'If width>1, set print width direct.'
                             | 'If width<1, set print width percent.'
                             |
--c, --color-system <STRING> | 'Chice color system.'
+-c, --color-system <STRING> | 'Choose color system.'
                             | ['standard', '256', 'truecolor', 'windows']
                             |
     --style <STRING>        | 'Set styles.'
diff --git a/richcat/modules/rich_makers/syntax_maker.py b/richcat/modules/rich_makers/syntax_maker.py
index 41a620e..c2091b4 100644
--- a/richcat/modules/rich_makers/syntax_maker.py
+++ b/richcat/modules/rich_makers/syntax_maker.py
@@ -36,4 +36,4 @@ def _read_file(self, filepath):
         return file_contents
 
     def _make_rich_text(self, file_contents, filetype, dic_style):
-        return Syntax(file_contents, filetype, line_numbers=True, word_wrap=True)
\ No newline at end of file
+        return Syntax(file_contents, filetype, line_numbers=True, word_wrap=True)
diff --git a/richcat/modules/rich_makers/template.py b/richcat/modules/rich_makers/template.py
index 5af4fb7..abe9e3d 100644
--- a/richcat/modules/rich_makers/template.py
+++ b/richcat/modules/rich_makers/template.py
@@ -6,7 +6,7 @@
 from rich.console import Console
 
 from ..consts._const import DIC_DEFAULT_VALUES
-from ..exceptions.exception import *
+from ..exceptions.exception import RichcatTerminalWidthGetError
 
 
 class AbstractRichMaker(ABC):
@@ -82,8 +82,8 @@ def _get_terminal_width(self):
             terminal width
         """
         try:
-            _, terminal_width = os.popen('stty size', 'r').read().split()
-            return int(terminal_width)
+            terminal_width = int(os.popen('tput cols', 'r').read())
+            return terminal_width
         except ValueError:
             raise RichcatTerminalWidthGetError()
 
diff --git a/richcat/modules/utils.py b/richcat/modules/utils.py
index d3bb276..6bf9454 100644
--- a/richcat/modules/utils.py
+++ b/richcat/modules/utils.py
@@ -1,4 +1,5 @@
 import os
+from importlib import import_module
 
 
 def extract_filename(path):
@@ -67,3 +68,23 @@ def calc_max_line_length(file_contents):
         max line length
     """
     return max(count_line_length(file_contents))
+
+
+def import_module_with_existence_confirmation(module_name):
+    """
+    The function to check if the module is installed and import the moduleto check if the library is installed
+
+    Parameters
+    ----------
+    module_name : str
+        module name
+
+    Returns
+    -------
+    : ModuleType or None
+        imported module. None if the module is not installed.
+    """
+    try:
+        return import_module(module_name)
+    except:
+        return None
diff --git a/richcat/richcat.py b/richcat/richcat.py
index cf7d1c0..cba8b99 100755
--- a/richcat/richcat.py
+++ b/richcat/richcat.py
@@ -1,17 +1,14 @@
 from __future__ import unicode_literals
 import sys
 import os
+import subprocess
 import argparse
 
-from rich.console import Console
-from rich.panel import Panel
-from rich.console import RenderGroup
-
 from .__information__ import __version__
 from .modules.consts._const import LST_COLOR_SYSTEM_CHOISES, DIC_DEFAULT_VALUES
 from .modules.consts._ext2alias_dic_generator import DIC_LEXER_WC, DIC_LEXER_CONST
-from .modules.exceptions.exception import *
-from .modules.utils import extract_filename, extract_extension
+from .modules.exceptions.exception import RichcatFileNotFoundError, RichcatIsDirectoryError, RichcatPermissionError, RichcatBrokenPipeError
+from .modules.utils import extract_filename, extract_extension, import_module_with_existence_confirmation
 from .modules.help import print_help
 
 from .modules.rich_makers.syntax_maker import SyntaxMaker
@@ -129,7 +126,17 @@ def print_rich(filetype, target_width, color_system, style, filepath=None, file_
     dic_style = interpret_style(style)
 
     # Print
-    if filetype == 'md':
+    if filetype == 'ipynb':
+        if import_module_with_existence_confirmation('jupyter') is not None:
+            out, err = subprocess.Popen(f'jupyter nbconvert --ClearOutputPreprocessor.enabled=True --to notebook --stdout --log-level WARN {filepath}'.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+            out, err = subprocess.Popen(f'jupyter nbconvert --stdin --stdout --to markdown --log-level WARN'.split(' '), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate(out)
+            file_contents = out.decode('utf-8')
+            filepath = None
+            filetype = DIC_LEXER_WC['md']
+        else:
+            filetype = DIC_LEXER_WC['json']
+
+    if filetype == DIC_LEXER_WC['md']:
         maker = MarkdownMaker(target_width, color_system, dic_style, filepath=filepath, file_contents=file_contents)
         maker.print(dic_style['pager'])
 
@@ -143,7 +150,7 @@ def print_rich(filetype, target_width, color_system, style, filepath=None, file_
 
 
 def main():
-    """ Args """
+    # Args
     parser = argparse.ArgumentParser(description="RichCat", formatter_class=argparse.RawTextHelpFormatter, add_help=False)
     parser.add_argument('filepath', type=str, metavar='FilePath', nargs='?', default=None, help='file path')
     parser.add_argument('-V', '--version', action='version', version='%%(prog)s %s' % __version__)
@@ -160,28 +167,28 @@ def main():
 
     if not args.help:
         if args.filepath is None:
-            if args.filetype==DIC_DEFAULT_VALUES['filetype']:
+            if args.filetype == DIC_DEFAULT_VALUES['filetype']:
                 args.filetype = 'text'
             args.file_contents = ''.join(sys.stdin.readlines())
         else:
             args.file_contents = None
-    """ Execute richcat """
+    # Execute richcat
     richcat(args)
 
 
 def richcat(args):
     try:
-        """ help """
+        # help
         if args.help:
-            args.file_contents,args.filetype,args.filepath = print_help()
+            args.file_contents, args.filetype, args.filepath = print_help()
 
-        """ Checking input error """
+        # Checking input error
         check_input_error(args)
 
-        """ Infering FileType """
+        # Infering FileType
         filepath, filetype = infer_filetype(args.filepath, args.filetype)
 
-        """ Print Rich """
+        # Print Rich
         try:
             print_rich(filetype, float(args.width), args.color_system, args.style, filepath=filepath, file_contents=args.file_contents)
         except BrokenPipeError:
diff --git a/scripts/get_version.py b/scripts/get_version.py
new file mode 100644
index 0000000..b9c3eba
--- /dev/null
+++ b/scripts/get_version.py
@@ -0,0 +1,6 @@
+import re
+
+with open('./richcat/__information__.py', 'r') as f:
+    init_text = f.read()
+    _version = re.search(r'__version__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
+    print(_version)
diff --git a/setup.py b/setup.py
index 28ea772..451a4f4 100644
--- a/setup.py
+++ b/setup.py
@@ -14,28 +14,28 @@ def _requirements():
 
 with open(path.join(root_dir, main_directory, '__information__.py')) as f:
     init_text = f.read()
-    version = re.search(r'__version__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
-    license = re.search(r'__license__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
-    author = re.search(r'__author__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
-    author_email = re.search(r'__author_email__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
-    url = re.search(r'__url__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
+    _version = re.search(r'__version__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
+    _license = re.search(r'__license__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
+    _author = re.search(r'__author__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
+    _author_email = re.search(r'__author_email__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
+    _url = re.search(r'__url__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
 
-assert version
-assert license
-assert author
-assert author_email
-assert url
+assert _version
+assert _license
+assert _author
+assert _author_email
+assert _url
 
 setuptools.setup(
     name=package_name,
-    version=version,
-    author=author,
-    author_email=author_email,
+    version=_version,
+    author=_author,
+    author_email=_author_email,
     description="rich cat command working on Python",
     long_description=long_description,
     keywords='cat, rich',
     long_description_content_type="text/markdown",
-    url=url,
+    url=_url,
     packages=setuptools.find_packages(),
     install_requires=_requirements(),
     classifiers=[
@@ -47,7 +47,7 @@ def _requirements():
         "License :: OSI Approved :: MIT License",
         "Operating System :: OS Independent",
         ],
-    license=license,
+    license=_license,
     entry_points = {
         'console_scripts': [
             'richcat = richcat.richcat:main',
diff --git a/sphinx/Makefile b/sphinx/Makefile
new file mode 100644
index 0000000..d4bb2cb
--- /dev/null
+++ b/sphinx/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS    ?=
+SPHINXBUILD   ?= sphinx-build
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/sphinx/conf.py b/sphinx/conf.py
new file mode 100644
index 0000000..861b335
--- /dev/null
+++ b/sphinx/conf.py
@@ -0,0 +1,72 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+import sys
+sys.path.insert(0, os.path.abspath('../'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'richcat'
+copyright = '2021, @yamamoto-yuta, @ShotaroKataoka'
+author = '@yamamoto-yuta, @ShotaroKataoka'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.viewcode',
+    'sphinx.ext.todo',
+    'sphinx.ext.napoleon',
+    'sphinx.ext.githubpages',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+# language = 'en'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+
+# -- Extension configuration -------------------------------------------------
+
+# -- Options for todo extension ----------------------------------------------
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
diff --git a/sphinx/index.rst b/sphinx/index.rst
new file mode 100644
index 0000000..e8313d7
--- /dev/null
+++ b/sphinx/index.rst
@@ -0,0 +1,21 @@
+.. richcat documentation master file, created by
+   sphinx-quickstart on Tue Feb  1 14:21:10 2022.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to richcat's documentation!
+===================================
+
+.. toctree::
+   :maxdepth: 4
+   :caption: Contents:
+
+   richcat
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/sphinx/make.bat b/sphinx/make.bat
new file mode 100644
index 0000000..153be5e
--- /dev/null
+++ b/sphinx/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+	echo.
+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+	echo.installed, then set the SPHINXBUILD environment variable to point
+	echo.to the full path of the 'sphinx-build' executable. Alternatively you
+	echo.may add the Sphinx directory to PATH.
+	echo.
+	echo.If you don't have Sphinx installed, grab it from
+	echo.https://www.sphinx-doc.org/
+	exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd


Test patch:
diff --git a/.github/workflows/upload-to-testpypi.yml b/.github/workflows/upload-to-testpypi.yml
new file mode 100644
index 0000000..e4eea7a
--- /dev/null
+++ b/.github/workflows/upload-to-testpypi.yml
@@ -0,0 +1,73 @@
+name: Upload to TestPyPI
+
+on:
+  push:
+    branches:
+      - release/v*
+
+jobs:
+  check_version:
+    runs-on: ubuntu-latest
+
+    outputs:
+      version: ${{ steps.get_version_in_code.outputs.version_in_code }}
+      version_matched: ${{ steps.compare_version.outputs.matched }}
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.7
+
+      - name: Extract richcat version from branch name
+        id: get_version_in_branch
+        run: echo "::set-output name=version_in_branch::$(echo ${GITHUB_REF#refs/heads/} | cut -d '/' -f 2 | sed 's/v//')"
+
+      - name: Get richcat version from code
+        id: get_version_in_code
+        run: echo "::set-output name=version_in_code::$(python ./scripts/get_version.py)"
+
+      - name: Compare version
+        id: compare_version
+        run: echo "::set-output name=matched::$([[ ${{ steps.get_version_in_branch.outputs.version_in_branch }} == ${{ steps.get_version_in_code.outputs.version_in_code }} ]]; echo $?)"
+
+  upload_to_testpypi:
+    runs-on: ubuntu-latest
+    needs: check_version
+    if: ${{ needs.check_version.outputs.version_matched == 0 }}
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Get pre-release count
+        id: get_pre_release_count
+        run: echo "::set-output name=pre_release_count::$(curl -s https://test.pypi.org/project/richcat/#history | grep -coE /project/richcat/0.5.0rc)"
+
+      - name: Set pre-release version
+        run: sed -i "s/${{ needs.check_version.outputs.version }}/${{ needs.check_version.outputs.version }}rc${{ steps.get_pre_release_count.outputs.pre_release_count }}/g" ./richcat/__information__.py
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.7
+
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          python -m pip install wheel twine
+
+      - name: Build
+        run: |
+          rm -rf ./richcat.egg-info/ dist/
+          python setup.py bdist_wheel
+
+      - name: Publish package to TestPyPI
+        uses: pypa/gh-action-pypi-publish@release/v1
+        with:
+          user: __token__
+          password: ${{ secrets.PYPI_API_TOKEN }}
+          repository_url: https://test.pypi.org/legacy/
diff --git a/debug/test.hoge b/debug/test.hoge
new file mode 100644
index 0000000..60dbc36
--- /dev/null
+++ b/debug/test.hoge
@@ -0,0 +1,3 @@
+echo "hello world"
+a=bbb
+echo $a
diff --git a/debug/test.js b/debug/test.js
new file mode 100644
index 0000000..60dbc36
--- /dev/null
+++ b/debug/test.js
@@ -0,0 +1,3 @@
+echo "hello world"
+a=bbb
+echo $a
diff --git a/debug/test.py b/debug/test.py
new file mode 100644
index 0000000..60dbc36
--- /dev/null
+++ b/debug/test.py
@@ -0,0 +1,3 @@
+echo "hello world"
+a=bbb
+echo $a
diff --git a/debug/test.sh b/debug/test.sh
new file mode 100644
index 0000000..60dbc36
--- /dev/null
+++ b/debug/test.sh
@@ -0,0 +1,3 @@
+echo "hello world"
+a=bbb
+echo $a
diff --git a/debug/test.zsh b/debug/test.zsh
new file mode 100644
index 0000000..60dbc36
--- /dev/null
+++ b/debug/test.zsh
@@ -0,0 +1,3 @@
+echo "hello world"
+a=bbb
+echo $a
diff --git a/tests/test_richcat.py b/tests/test_richcat.py
new file mode 100644
index 0000000..0c68327
--- /dev/null
+++ b/tests/test_richcat.py
@@ -0,0 +1,31 @@
+import sys
+
+import pytest
+
+sys.path.append('..')
+import richcat.richcat as richcat
+import richcat.richcat.modules.exceptions.exception as exc
+
+richcat_init = richcat
+richcat = richcat.rc
+def create_args(filepath):
+    class Args():
+        def __init__(self, filepath):
+            self.filepath = filepath
+    return Args(filepath)
+
+@pytest.mark.parametrize(
+        "args, error", [
+            (create_args("aaa"), exc.RichcatFileNotFoundError),
+            (create_args("debug"), exc.RichcatIsDirectoryError),
+            (create_args("debug/permission.txt"), exc.RichcatPermissionError),
+            (create_args("debug/test.js"), None),
+            ]
+        )
+def test_check_input_error(args, error):
+    try:
+        richcat.check_input_error(args)
+        assert error is None
+    except Exception as e:
+        assert e.__class__ == error(args).__class__
+
diff --git a/workflow-test.sh b/workflow-test.sh
new file mode 100755
index 0000000..6de1381
--- /dev/null
+++ b/workflow-test.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+if [ "$1" = "-h" -o "$1" = "--help" ]; then
+  echo "  Args list"
+  echo "    --help : show help."
+  echo "    <None> : normal pytest."
+  echo "    cov    : pytest with code coverage."
+  echo "    cov CI : codecov CI mode."
+else
+  chmod 000 ./debug/permission.txt
+  if [ "$1" = "cov" ]; then
+    if [ "$2" = "CI" ]; then
+      mkdir ./coverage
+      pytest --cov=./richcat --cov-report=xml ./tests
+    else
+      pytest --cov=./richcat ./tests
+    fi
+  else
+    pytest
+  fi
+  chmod 644 ./debug/permission.txt
+fi
+