こうかの雑記

こうかの雑記

昔の懐かしいこと、ubuntuのこと、その他いろいろ

還付されました

 2月1日の記事

koukaforest.hatenablog.com

で「確定申告ネタはこれで終りです。」と書きましたが、昨日、銀行ATMで通帳への記帳を行ったところ2月13日付で還付されていました。    eTAXで申告をすると還付が早いとありましたが本当ですね。申告日付は1月28日でしたので16日で還付されたことになります。

 今回は2万円ちょっとありました。僅かではありますが助かります。

これで、本当に確定申告ネタはおわりです。

還付申告しました

還付申告

 年金受給者なのですが確定申告と言った方が一般的だと思いますので今までそのように言ってきました。しかし年金受給者の場合は還付申告と言う方が正確なようです。  1月に「税務署から確定申告の案内が届いた」の記事を書いていますが、この時に送付されてきた案内の文言で初めて還付申告という言葉を知りました。 その時の文言は次の通り

 例年、税務署の確定申告会場は、確定申告期間中、大変混雑が予想されますので、今回、年金受給者の方を対象に御案内する還付申告会場をご利用願います。

 還付申告という言葉にひっかかり調べたところ、確定申告とはこれから収めるべき税金を申告するためのもので、還付申告は収めすぎた税金を返してもらうためのものです。  また確定申告の申告期間は(今年は)2月17〜3月16日ですが、還付申告の申告期間は翌年1/1から5年間。

 ということで年金受給者の殆どの方は還付申告になります。それで確定申告期間の2月17〜3月16日を待たずに申告することが出来ます。

 ちなみに税務署から案内された日程は2月6日でした。

申告送信

 「e-TAXで確定申告はこんな感じでできます」の記事で書いた様に、その時点では一つの資料の入手が遅れていたのですが、ようやく手に入り必要項目の全てを入力できましたので、送信しました。

 送信するまでに何度確認したことか。途中で保存したりしていますので、呼び出す度に確認していたと思いますしね。最後に入力モレがないか確認して送信しました。

 送信すると、「令和01年分の申告書等送信簿」と「令和01年分の所得税及び復興特別所得税の申告内容確認票B(第一表)、同じく(第二表)が印字できます。印字できると言ってもpdfファイルの形でダウンロードすることですが。ダウンロード後プリンタで印刷するなり、pdfのまま保存するなりします。  印刷して控除資料と合わせて5年間保存しておくのが良いと思います。こうしておけば、何時提出を求められても一式揃えて提出できますから。

 最後にe-TAXでの確定申告についてのアンケートがあります。殆どの質問に対する回答は選択式で、一つだけ感想を書けるようになっていました。多分無理でしょうけれどID・パスワード方式を続けて欲しいことを書いておきました。

 というわけで、ubuntu + Firefox という環境ですが難なく還付申告できました。  マイナンバーカード方式一本になったら…多分ubuntuの環境では無理かも知れません。

 確定申告ネタはこれで終りです。

pythonでmarkdownファイルに目次を付けたり外したりする

 markdown記法を「はてな」のブログ記事の作成、メモやマニュアルの作成に利用しています。ブログ記事だけであれば問題はないのですが、その他のビューワで見る資料、マニュアルづくりでは残念なことがあります。それは目次の作成です。  markdown記法そのものには目次についての規則が無いようです。

 「はてなブログ」の記事作成では'[:contents]'と書いておくだけで、その箇所に目次が挿入されて表示されます。また、Markdownエディタのtyporaでは'[toc]'と書くだけで、同様に目次が表示されます。

 私はブラウザのFirefoxにアドオンのMarkdown Viewer、Markdown Viewer Webextを追加してブラウドで見ていますが、'[toc]'や'[:contents]'は目次に変換されず、そのまま表示されてしまいます。

 ネット上で探すとマイクロソフトVisual Studio Code拡張機能を使うと簡単にできるという記事を沢山見つけました。しかしVScodeをインストールする気は今のところありません。ubuntuには標準でpython3があるのだから、これを使ってなんとかしようと思いました。拙い技術力しか持ち合わせていませんが作ってみましたので紹介します。

■対象環境

  • ubuntu18.04
     他の環境でも大丈夫だとは思いますが、行の終端は'\n'でやっています。多分Windowsは'\r\n'に変更する必要があるんだろうなと思います。
  • python3.6
  • tkinter  ubuntutkinterがインストールされてない場合は次のコマンドでインストールできます。
$ sudo apt-get -y install python3-tk

■仕様

目次の挿入機能

 オリジナルmdファイルには、目次を表示したい位置に次の行を入れておきます。

[toc]

 出力されるmdファイルには、"[toc]"のある行がカットされて代わりに次のような行が追加されます。

<h2>目次</h2>

  [文法](#anchor0002) <br>
   [コメントの表記](#anchor0003) <br>
  [書き出し](#anchor0004) <br>

 目次部分は以上のように、本文中の見出し部分へのリンクの行になります。  また本文中の見出しの前には次のように"<a"タグが挿入されます。

<a id='anchor0002'></a>
## 文法

 文法説明

<a id='anchor0003'></a>
### コメントの表記

 コメント説明

<a id='anchor0004'></a>
## 書き出し

 書き出し説明

 "a2"タグが要所要所に挿入されます。

 この例の表示は次の様になります。

f:id:koukaforest:20200125160100p:plain

目次の除去機能

 資料に改変を加えると目次の項目も変わるかも知れません。既にある目次関係を取り去ってもう一度目次を作り変えたほうが良いと思うことでしょう。そのために既存の目次関係の行を取り除いて、目次を付ける前の状態に戻します。

 "<h2>目次</h2>"の文字列を"[toc]"に置き換えます。
 次に"#anchor"含む行、すなわち目次を除去します。
 "<a id='anchor'>"の文字列がある行を全て除去します。

■実行

 コマンドラインからパラメータで対象ファイルを指定する方法は採リませんでした。スクリプトを指定する起動させるとファイル選択の画面が出るようにしています。ここはtkinterを使っています。

 ファイルの一覧が表示されるので、そこから対象ファイルを選びます。スクリプトが保存されているフォルダーが表示されますが、フォルダー移動して目的のファイルを探して選択します。

 目次を付けるのか、目次を除去するのかは選択したmdファイルを調べて自動判断されて処理されます。  古いファイルは拡張子に'bak'が追加されて保存されます。

■注意

 目次の除去の際には"<h2>目次</h2>"、"#anchor"、"<a id='anchor'>"の文字列をその他の目的で含む場合、それら文字列が消えてしまいますので注意下さい。

 例えば、この説明記事のmdファイルの様な場合には説明のためにこれらの文字列を含ませていますが、その行が消えてしまい説明にならなくなると思います。

 ご利用は自己責任ということでお願いします。

pythonスクリプト

#!/usr/bin/env python3
"""
mdtoc.py
    markdownファイルに目次を追加する、または除去する。
author  s.k
create date 2020/01/22
"""
import tkinter
import tkinter.filedialog
import tkinter.messagebox
import os

block = False   # md記法で"```"で囲まれているかどうか
seq   = 0       #見出し項目のカウント
"""
    与えられた文字列から見出しレベルと見出し、参照名、行番号を取り出す。
    見出しでなければ (-1, '') を返す
    尚、'```'で挟まれている場合は無視する。
        見出しレベル:#の数
            見出し
            参照名 anckor+連番
            行番号 元ファイル上で何行目かを示す。
"""
def get_header(text):
    global block, seq
    if text[0:3] == '```':
        if block:
            block = False
        else:
            block = True
    if text[0] != '#' :
        return [-1, '', 0]
    if block == False:
        headdic={'#':1, '##':2, '###':3, '####':4, '#####':5, '######':6}
        s      = text.split(' ',1)
        lvl    = headdic[s[0]]
        header = s[1].strip()
        seq = seq + 1
        seqs    = 'anchor' + str(seq).zfill(4)
    else:
        lvl = -1
        header =''
        seqs=''
    return [lvl, header, seqs]

"""
    目次項目を取り出す。
"""
def get_toclist(infile):
    try:
        inf = open(infile, 'r')
    except Exception as err:
        print(infile, 'オープンに失敗しました。')
        return False
    lst=[]
    c = 0
    for l in inf:
        header = get_header(l)
        c = c +1
        header.append(c)
        if header[0] > 0:
            lst.append(header)
    inf.close()
    return lst
"""
    指定行番号( [toc] )の一つ前のレベルを取り出す。
"""
def getstartlevel(lst, line):
    level = -1
    for l in lst:
        if l[3] < line:
            level = l[0]
    return level

def get_anchor(lst, line):
    for l in lst:
        if l[3] == line:
            return l
    return []
"""
    見出しの字下げ空白を作る。受け取るnはレベル
"""
def makindent(n):
    indent=''
    c=0
    while c < n:
        indent = indent + ' '
        c = c + 1
    return indent
"""
    目次部分を出力する。
"""
def put_toc(outf, lst, startlevel):
    outf.write('<h2>目次</h2>\n\n')
    for l in lst:
        if l[0] > startlevel:
            indent = makindent(l[0])
            outl = (indent + '[' + l[1] + '](#' + l[2] + ')  \n')
            try:
                outf.write(outl)
            except Exception as err:
                print('目次の書き込みで書き込み失敗しました。')
                return False

"""
指定ファイルに目次を作る
"""
def mak_toc(infile):
    lst = get_toclist(infile)   # 目次項目のリストを得る
    try:
        inf = open(infile, 'r')
    except Exception as err:
        print(infile, 'オープンに失敗しました。')
        return False
    outfile  = infile + 'work'
    try:
        outf = open(outfile, 'w')
    except Exception as err:
        print(outfile, 'オープンに失敗しました。')
        return False
    startlevel = 1
    lcnt = 0
    for l in inf:
        lcnt = lcnt + 1
        t = l.find('[toc]', 0)  # '[toc]'があるか調べる
        if t != -1:
            # あればその行はコピせずに目次を埋め込む
            startlevel = getstartlevel(lst, lcnt ) 
            put_toc(outf, lst, startlevel)
        else:
            try:
                anchor = get_anchor(lst, lcnt)
                if anchor != []:
                    ancstr = "<a id='" + anchor[2] + "'></a>\n"
                
                    outf.write(ancstr)
                outf.write(l)
            except Exception as err:
                print('目次作成で書き込み失敗しました。')
                return False
    inf.close()
    outf.close()
    sw = 0
    bakfile = infile + 'bak'
    try:
        os.rename(infile, bakfile)
    except Exception as err:
        print('元ファイルrename失敗しました。', infile)
        sw = 1
    try:
        os.rename(outfile, infile)
    except Exception as err:
        print('仮ファイルrename失敗しました。', outfile)
        sw = sw +1
    if sw == 0:
        print('目次付け終りました。')
        return True
    return False

"""
指定ファイルから目次に関する行を取り除く
"""    
def rm_toc(infile):

    try:
        inf = open(infile, 'r')
    except Exception as err:
        print(infile, 'オープンに失敗しました。')
        return False 
    outfile= infile + 'wrk'
    try:
        outf = open(outfile, 'w')
    except Exception as err:
        print(outfile, 'オープンに失敗しました。')
        return False 
    for l in inf:
        p = l.find('<h2>目次</h2>', 0)
        if p != -1:
            try:
                outf.write('[toc]')
            except Exception as err:
                print('目次取り除きで書き込み失敗しました。')
                return False
            # 目次部分カット
            continue

        p = l.find("](#anchor",0)   # 目次部分?
        if p == -1:
            p = l.find("<a id='anchor", 0) # 見出しのアンカー?
            if p == -1:
                # いずれでもないので出力
                try:
                    outf.write(l )
                except Exception as err:
                    print('目次取り除きで書き込み失敗しました。')
                    return False
            else:
                pass    # 目次またはアンカーなので無視
    inf.close()
    outf.close()
    sw = 0
    bakfile = infile + 'bak'
    try:
        os.rename(infile, bakfile)
    except Exception as err:
        print('元ファイルrename失敗しました。', infile)
        sw = 1
    try:
        os.rename(outfile, infile)
    except Exception as err:
        print('仮ファイルrename失敗しました。', outfile)
        sw = sw +1
    if sw == 0:
        print('目次除去終りました。')
        return True
    return False

"""
    指定ファイルに'[toc]'と目次のいずれがあるかを確認する。
    結果は'[toc]'があれば'mk'を、目次があれば'rm'を返す。
"""
def checkread(infile):
    try:
        inf = open(infile, 'r')
    except IOError as err:
        print(infile, '確認オープンに失敗しました。')
        return 'error' 
    toc = False
    mokuji = False
    for l in inf:
        p = l.find('[toc]',0)
        if p != -1:
            toc = True
        p = l.find('<h2>目次</h2>')
        if p != -1:
            mokuji = True
    inf.close()
    if toc:
        return 'mak'
    if mokuji:
        return 'rm'
    return 'error'

def main_rtn():
    root = tkinter.Tk()
    root.withdraw()     # 小さなウインドウが出るのを止める
    tkinter.messagebox.showinfo('mdtoc.py','対象の.mdファイルを選択して下さい。')
    fname = tkinter.filedialog.askopenfilename(title='mdtoc.py')
    root.destroy()
    # fname = "/home/sk/デスクトップ/pythonmemo.md"
    syori = checkread(fname)

    if syori == 'mak':
        print('目次を作成')
        mak_toc(fname)
    else:
        print('目次を除去')
        rm_toc(fname)

if __name__ == '__main__':
    main_rtn()

 何か問題があれば、教えて下さい。  メールはこちら https://fm.sekkaku.net/mail/1201407490/