Gitの学習ツール「Git-it」

Visual Stusdio Code(以下VS Code)でGitを使えるようになりたい、Atom + SourceTree から卒業しよう!ということでVS CodeでGitについて調べたものの、分からないことだらけだったのでGit(GitHub)についてイチから学習しようと思いました。

Visual Studio Code の git 連携機能と git コマンドについて (2018/05/23) - Qiita

とても今後役立ちそうなこちらの記事に「Git-itがおすすめ(日本語で解説してくれる)」とあったのでやってみました。

本日のつまづき

ずばりなかなか「Git-it」が見つからなかったことです。
しょうもない...。

GitHub - jlord/git-it-electron: Git-it is a (Mac, Win, Linux) Desktop App for Learning Git and GitHub

最初にページを開いて真っ先に目に入る、この緑のボタン「Read the guide」を押して、GitHubのガイドを読んでリポジトリを作ってブランチを作ってコミットしてプルリクをしてマージして...ということをしましたが、一向に日本語が出て来ず。

f:id:yokoyoko_115:20200503014808p:plain

次に同じページの緑のボタン「Clone or download」を押して確認しましたが、違いました。

正解はこのページの「releases」というアンカーテキストから移動したページ

Releases · jlord/git-it-electron · GitHub

からダウンロードです。

「Git-it」からの発見

ProgateのGitレッスンと内容は同じかと思いきや、こちらの方が盛りだくさんでした。

Git-itでは、練習で作成したローカルリポジトリをGit-itに登録して、レッスンの区切りごとに「VERIFY」ボタンでできているかチェックできます。

以下GitHub、gitコマンド初心者である私が引っかかったところをメモします。

git commit の前は git add する

Git-itでは練習として

一回コミットしたファイルをもう一度変更・保存して git diff で差分を確認して、コミットしましょう

と出てくるので、その通りにすると、

On branch master
Changes not staged for commit:
    modified:   readme.txt

no changes added to commit

と、コミットできないようなことを言われました。

調べると、

“はじめのGit”――超基本的な作業フローと5つのコマンド (3/3):こっそり始めるGit/GitHub超入門(2) - @IT

「Changes not staged for commit」はファイルが変更されているのに変更がステージングエリアにない(インデックスされていない)ときに出てくるメッセージだそうです。

確かにSourceTreeでもコミット前に毎回ファイルをチェックする操作をしていました。
git addgit commit はセット!覚えます。

user.username はGit−it独自のもの

git config の設定値でuser.username というものが出てきます。Git-itの日本語版では「GitHubと同じユーザー名にしてください」と出てきます。
英語版では↓

f:id:yokoyoko_115:20200504004631p:plain
Git-itテキストがコピペできず、Google翻訳を断念し、雰囲気で解釈
どうやらuser.username はGit−itでしか使わないもののようです。

フォーク、クローン

GitHubで人様のリポジトリをコピーして自分のアカウントに置くフォーク。これはGitHub上で操作します。
さらにそのリポジトリをローカルにコピーするクローン。
コピー先に移動して

git clone <URL>

です。

フォークは初めて知りました。
プルリクのための機能、元のリポジトリを汚さずにコピーしたリポジトリを更新してプルリクする。共有されていないリポジトリに対して行うことが多いようです。

共有されているリポジトリ、同じプロジェクトを複数人で触るときなどは、フォークを使わず、そのままブランチを切って更新、プルリクをする、というパターンを取ります。

GitHub Pages

GitHubは'ph-pages'という名前のブランチにあるファイルを自動的に静的なWebサイトとしてホストしてくれる機能があります。

すごいですね。なんて太っ腹!

2020年5月現在では、ブランチ名は自由に設定できそうです。

【初心者向け】Github pagesでwebページを公開する方法 - Qiita

ページを作るときが来たらまた調べようと思います。

ブランチ

ブランチの作成: git branch ブランチ名
ブランチの確認: git branch  今どのブランチにいるか * で記されます
ブランチの切り替え(チェックアウト): git checkout ブランチ名

pushするときの注意点

push先のリポジトリ、ブランチを意識する

コマンドで push するとき

git push origin ローカルリポジトリのブランチ名:リモートリポジトリのブランチ名

となります。

ローカルとリモートでブランチ名が同じ場合は : で区切らずブランチ名1つでOKです。

Git-itではGitHubの「patchwork」というリモートリポジトリをフォーク、クローンして、ローカルリポジトリに「add-<USERNAME>」というブランチを作りました。

ファイル更新後のpushコマンドは git push origin <BRANCHNAME> なのですが、
そこで何を思ったか勘違いをしてgit push origin patchwork と、リポジトリ名を入れてしまいました。すると

error: src refspec patchwork does not match any
error: failed to push some refs to 'リモートリポジトリのURL'

というエラーが出ました。
勘違いにつぐ勘違いで、それじゃあ git push origin add-<USERNAME>:patchwork だ!とpushしたところ、「VERIFY」とチェックしてもOKとなりませんでした。

リポジトリ名とブランチ名の混同問題。気をつけます。

リモートリポジトリにローカルと同名のブランチがなければ新しく作られる

しっかりした確証はないのですが、そのようです。
前述のようにブランチ名が異なるpushをしたのですが、リモートリポジトリにこれまでなかった「patchwork」ブランチが作られていました。

新しくリモートに作られたブランチが自分には見えるのにリポジトリを共有している人には見えなかったりなど、いろいろ問題が起こるそうなので、覚悟しておきます。

コラボレーター(Collaborators)

GitHubのユーザーでかつ誰かのリポジトリにアクセスして編集することが許された権限を持つ人たちのことです。

GitHubの Settings >Manage access というメニューにありました(2020年5月現在)

フェッチ

gitがバージョンアップして「pull = fetch + merge」という解釈で良いとありました。

【入門者向け】Gitのfetchコマンドについて図を用いて解説

フェッチをすると、リモートの変更を追跡するためのブランチ「リモートトラッキングブランチ(origin/master)」がローカルに作成されます。

そしてローカルのmasterブランチを最新にするためには、masterブランチから
git marge origin/master とマージします。

これまで謎だった origin/master の正体が少しわかりました。

またGit-itには、
git fetch --dry-run で「Pullする前にリモート上で行われた変更を見てみる」 とありました。
pullではなくfetch?引っかかる表現だな...という印象なのですが、おそらく --dry-run は処理のシュミレートをするオプションなので、fetch時により詳細な内容が表示されるのではないかと想像しました。おいおい確認できれば。

最後までやらずに終了

Git-it最後のステップは、練習用のGitHubリポジトリにプルリクを送り、マージされた内容をプルする、というものでした。

こちらに自分のユーザー名のテキストファイルが追加されます。

patchwork/CONTRIBUTORS at gh-pages · jlord/patchwork · GitHub

Git-it修了生の方々がずらり。
おもいっきり日本人とわかるユーザー名にしてしまったことを少し後悔して、操作の流れを読んで終わりにしました(いくじなし)。

***

コマンドでGitを覚えると、SourceTreeなどのGUIの操作はこういうことだったのか、という気付きがありました。嫌でも黒い画面の英文を読まなくてはいけないので、ちゃんとした理解が必要で、「なんとなく」の操作が減りそうです。

...忘れてはいけないのは、私はVS CodeでGitを使う方法を模索しているということです。
黒い画面慣れしてきたので、VS Codeでもやっていけそうです。

Visual Stusdio Codeに乗り換えます

エディタはAtomを使っていましたが、最近プロジェクト内のファイル名を変えたり、プラグインを使ったFTPアップロードをしようとすると落ちることが多々。
そこでお勧めいただいたVisual Stusdio Code(以下「VSCode」)に乗り換えを決めました。

Visual Studio Codeのうれしい機能を使いこなして、初心者を最速で脱出する!《VSCode実践入門》 - エンジニアHub|若手Webエンジニアのキャリアを考える!

↑詳しく書かれていて参考になりそうです。
インストールから設定の中でつまずいた部分をメモしました。

☆現在のバージョンは
March 2020 (version 1.44)
です。

***

VSCodeを使うにあたって、自分に一つ制約を設けました。

VSCodeは英語表示のまま

半分意地です。これからGitHubを積極的に使っていこうとしているので、少しでも英語のUIに慣れようかと思いました。そしてちょっとかっこいい。

PATHが通っていない

VSCodeインストール後にコマンドライン

code -v

と確かめたところ、

zsh: command not found: code

と返ってきてしまいました。

codeコマンドが使えない状態なのは分かりましたが、使えないとどう不都合なのか、どうPATHを通したらいいのか調べました。

PATHの通し方

まず、私はシェルはzshを使っています(echo $SHELL とコマンドを打つとデフォルトシェルが確認できます)。

そもそも「PATHを通す」とは

PATHを通すとは? (Mac OS X) - Qiita

こちらも参考にさせていただきました

macでPATHを通す方法 - zsh/bash - Qiita

コマンド検索パス(コマンドサーチパス:シェルがコマンド実行ファイルを探しに行くパス)を追加すること。

実行ファイルまでのパスを毎回書くのは大変なので、コマンド検索パスをシェルの設定ファイルに追加しましょう、ということです。

設定ファイルはホームディレクトリにある .zshrc です(bashの場合は .bash_profile)。
もし設定ファイルがない場合はこの名前で作成します。

.zshrc を開くと

eval "$(anyenv init -)"

これだけ...おかしい。
もっと色々パスが書かれていると予想していたので、ここにVSCodeの実行ファイルのパスを入れるのは違う気がしました。

VSCodeからPATHを通す

後からPATHを通す設定がありそうとは思っていましたが、やはりありました。
英語表示によりメニューの解読を脳が避けているため、発見が遅れました(笑)

参考:

Visual Studio Code の初期設定と最低限必要な拡張機能 - フロントエンド向け - - Qiita

コマンドパレットとは、VSCodeの機能(Command)にアクセスできるものです。
メニューからは View > Command Palette...
ショートカットは [Command] + [Shift] + [P](Mac
です。

(...脱線しますが

⇧:Shift
⌘:Command

というのは個人的に忘れがちです。
この記号はどうやって打ったら出るのでしょうね...。)

コマンドパレットに >shell と入れるとshellに関する機能が検索されます。

f:id:yokoyoko_115:20200429010442p:plain

となっていました。
「recently used」の覚えはないですが、デフォルトの設定なのでしょうか。
「Shell Command: Install〜」を選択し、再びコマンドラインcode -v で確認すると、バージョンが確認できました。
(その下に数字と英語の羅列が続くのですがこれはバージョンの識別子...?)

ついでに .zshrc を開いて確認してみると、VSCodeのパスは追加されていませんでした。
きっと別経由で追加されているのでしょう(詮索は別の機会に)。

参考にさせていただいた記事を見ると、どうやら「ターミナルから VS Code を利用する」とあるように、VSCodeを利用するのに必ずしもPATHを通す必要はないようです。考えてみればそうですね...。
今後黒い画面とVSCodeを使いこなしているかもしれないので、初めのうちに設定しておいてよかったと思います。

もろもろの設定

メニューからは Code > Preferences > Settings
ショートカットは [Command] + [,](Mac
です。

とても設定項目が細かい!

他の方が紹介してくださっている「おすすめ初期設定」を参考に設定したほうが無難です。
検索窓があるのでそこから設定項目を探し出して設定していきます。

設定の範囲

VSCodeには4つの設定範囲があります。

vscodeの利用に必須な”ワークスペース”の概念 | 今日も元気にIT屋さん

vscodeは4つの設定定義レベルが存在する。
1. vscode全体の設定(プログラム規定値)
2. vscode全体の設定
3. ワークスペース単位の設定
4. フォルダ単位の設定

私が行った操作は「2.」です。
ワークスペースをまだ作っていないので、まずは登録してみます。

ワークスペースの追加:
File > Add Folder to Workspace...

フォルダを指定して開くと、サイドバーに「UNTITLED」として表示されます。

ワークスペースの保存:
File > Save Workspace As...

保存するとワークスペースに指定したフォルダ内に ワークスペース名.code-workspace というファイルを保存する流れになります。

ワークスペース登録後に設定を見てみると、「User」以外に設定できる範囲が増えています。

f:id:yokoyoko_115:20200430005307p:plain

ワークスペースごとに設定できるのが良い、という記事を見かけました。
複数のルートフォルダをワークスペースでひとまとめにできる。その状況になってみたら素晴らしさに気付くのだと思います。

***

実はまだVSCodeでコード書いていないのですが、設定の多さにお腹いっぱいになってしまったのでここで終わりにします。

多機能なVSCode。ある程度使いこなせるといいです。
今後の試みとしては、cssもEmmetで書いてみようと思います!

英語表示にくじけそう

調べていると、見る記事見る記事全てVSCodeが日本語画面。
敷居を下げるためにも日本語にするべきか...。

次回記事を書くことがあったら日本語になっているかもしれません(笑)

GitHubで初push

Gitをしっかり学ぼう、という熱が出てきたので、ProgateでGitのレッスンを受けました。

「Gitの環境構築をしよう!」というコラムでGitHubの使い方が書かれていて、せっかくなので制作中のHugoサイトをGitHubで管理しようと思いました。

サイトに新しくプラグインを入れたり、新しいものの導入の際は、マニュアル通りに進めるのが失敗しない道筋です。
いきなり2段飛ばしで導入してあれ動かない??という経験を何度もしていますが、今回もやってしまいました。
つまづいた部分も記録します。

ちなみに私、GitHubはアカウントはあるものの、ほぼ使用経験ゼロです。
せいぜい人様のソースをダウンロードするぐらいです。 これからがんばろう...。

コマンドラインでGit

現在Sourcetreeを使っています。Progateはコマンドラインで紹介されていたので、gitコマンドを覚えるいい機会でした。

ローカルにあるHugoサイト(この時点では「test」フォルダに入れています)をローカルリポジトリとし、GitHubにpushするまでの経緯です。

Gitのインストールの確認

git --version

git version ***と出てきたのでインストール済みでした。
(別の何かをインストール時にgitも一緒にインストールされていたような)

Gitのユーザー名とメールアドレスの設定

git config --global "ユーザー名"
git config --global "メールアドレス"

ちなみに --global というオプションを調べると、gitのconfig(設定)がユーザーの範囲で適用されるそうです。

--system でシステム全体、オプションなしでリポジトリの範囲で適用されるユーザー名、メールアドレスになります。

システム → global(ユーザー)→ local(リポジトリ
の順でそれぞれのconfigファイルを見て、あれば設定値が上書きされていきます。
優先度が最も高いのは個別のリポジトリに設定されたconfigになります。

参考:
Git - Git の設定

GitHubのアカウント作成、ログイン

アカウントがあるので私の場合はログインするだけです。
二段階認証(2要素検証)で設定されているので、ワンタイムパスワードを使ってログインしました。

GitHubにリモートリポジトリ作成

メニューバーの「+」→「New repository」
→「Repository name」にプロジェクト名を入力("hugosite"と入力)
→「Create repository」ボタン

でできました。中身はまだ空です。
ここにローカルのファイルをpushしたいです。

ローカルリポジトリの初期化

cd コマンドでhugoサイトのあるフォルダまで移動します。

そのフォルダ以下をGit管理する

git init

すると、そこに .git フォルダが作られます。リポジトリを管理するのに必要なファイルが入っています。

push先のリモートリポジトリの設定

あらかじめGitHubリポジトリのURLをコピーしておきます。

リモートリポジトリの追加

git remote add origin <URL> 

origin はリモート名です。一般的にoriginが使われます。
<URL> は先程コピーしたリモートURLになります。
先程GitHubで「hugosite」と入れた「Repository name」に合わせなくて良いのだろうか、と疑問を持ちましたが、originがよさそうです。

Gitでよく使う「origin」って何?わかりやすく説明します - Reasonable Code

originとは リモートリポジトリのアクセス先に対してGitがデフォルトでつける名前です。

意識していないうちに自動的に origin と付いている場合もあることから、合わせたほうがいいという印象を受けました。むしろオリジナルなリモート名をつけられたら困惑しそうです。

このリモートリポジトリの追加の際にorigin とリモートURLが紐付くというのは覚えておきたいです。

ファイルを追跡対象にする、ステージングする

git add .

git add は「新しいファイルの追跡を開始する」「ファイルのステージング」「マージ時に衝突が発生したファイルに対する「解決済み」マーク付け」で使います。

Git - 変更内容のリポジトリへの記録

今回はすべてのファイルをpushしたいので引数を git add . としました。一応うまくいったと思います。

git add -u と git add -A と git add . の違い | note.nkmk.me

コミットする

git commit -m "コミットメッセージ"

-m オプションでメッセージを付けられます。
かっこよく英語でメッセージ残せるようになりたいです(わかりやすさ重視で日本語)。

プッシュする

git push origin master

エラー!

上記の通りpushすると、まずGitHubのユーザー名を聞かれました。
さらにパスワードを聞かれました。
すると、

remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/ユーザー名/hugosite.git/'

と出ました。認証されなかったようです。

試したこと

Gitのユーザー名とGitHubのユーザー名をあわせる

Gitの設定でユーザー名を登録しましたが、そこがGitHubと合っていないからなのかも?と思い、git config --global "ユーザー名" で設定し直しました。

...結果ユーザー名は関係ありませんでした。

ちなみに、デフォルトではGitのユーザー名でコミットすることになるそうです。

$ git push した際に、GitHub のアカウント名で push するには - poyopoyoのブログ

ローカルリポジトリのフォルダ名とGitHubリポジトリ名をあわせる

結果同じじゃなくても大丈夫でした...SourceTreeでもそうじゃないか...。

ここはGitHubの方の「Repository name」を変更し、追加したリモートリポジトリを一度削除してから git remote add origin <URL> をやり直しました。

GitHubリポジトリ名の変更:
該当するリポジトリのページの「Settings」タブより。

登録されているリモートリポジトリの確認:

git remote -v

リモートリポジトリの削除:

git remote rm origin

git remote add を取り消す方法 - Qiita

なお、リモートリポジトリの再登録をしても、git add . をやり直す必要はありませんでした。

本日のつまづき

GitHubを普通に使われている方にとっては常識なのかもしれません。

二段階認証(2要素検証)の設定ではHTTPS接続でpushできない

下記の通り、可能ではあるようです。

Githubで2段階認証を設定しhttpsリポジトリにpushする - hatappi.blog

しかし特別こだわりはないので、SSHのURLを使って無事pushできました。
ユーザー名、パスワードも聞かれずにあっさりと...。

めでたしめでたし。

Hugo - 中華フォントを直す(cssファイルの読み込み)

Hugoの無料配布されているテーマをインストールして、最初に直したい所が、
フォント

でした。

今回インストールしたテーマ「cleanwhite」は、おそらく中国方面の方が作られたようで、いわゆる「中華(中国語)フォント」が使われています。

f:id:yokoyoko_115:20200404000029p:plain
「記」が気になる

そこでcssを見てみると

body {
font-family: -apple-system,"Helvetica Neue",Arial,"PingFang SC","Hiragino Sans GB",STHeiti,"Microsoft YaHei","Microsoft JhengHei","Source Han Sans SC","Noto Sans CJK SC","Source Han Sans CN","Noto Sans SC","Source Han Sans TC","Noto Sans CJK TC","WenQuanYi Micro Hei",SimSun,sans-serif;
}

知らないものがいっぱい...。

調べた限りでは、
PingFang SC・・苹方ゴシック体。iPhoneの中華フォント
Hiragino Sans GB・・・ヒラギノ角ゴ簡体中文
STHeiti・・・中華フォント。「ST」と付くものは“埋め込み”ができないそうです
Microsoft YaHei・・・Windows Vista簡体字中国語版のUI用フォント
Microsoft JhengHei・・・Windows 10 でインストールされる繁体字中国語フォント

...と、中華フォント三昧でした。

日本語フォントにする

このままでは気持ち悪いのでフォントを変えます。

フォントの設定はcssのminファイルに書かれていたので、新しくcssファイルを作って読ませようと思います。

themes/hugo-theme-cleanwhite/layouts/partials/head.html がテンプレートのhead要素内にあたるので見てみます。

head.html

 <!--  Custom CSS  -->
{{ range .Site.Params.custom_css -}}
<link rel="stylesheet" href="{{ . | absURL }}">
{{- end }}

ここを何とかすればよさそうです。

{{ }} とは

Go言語のテンプレート機構で使われる書き方でした。

静的サイトジェネレータ「Hugo」と技術文書公開向けテーマ「Docsy」でOSSサイトを作る | さくらのナレッジ

Go言語では、text/templateやhtml/templateというテンプレート機構が標準で用意されている。Hugoではこのテンプレート機構をそのままレンダリングに使用している。

Go言語を少しかじったときには {{ }} は出てきませんでした。
書式を調べていくうちに慣れるといいですが。

head.html内では、.Site.Params.custom_css で配列名を指定していて、{{ range }}{{ end }}の間でループして配列の値を{{ . }}で出力しているみたいです。

ちなみに、{{ -- }} はそれぞれ前後の空白を削除する書き方です。
実際に後述するconfig.tomlのcustom.css部分のコメントアウトを外してみると、<link>要素が改行なしに出力されます。

テンプレート機能を使用する (text/template, html/template) | まくまくHugo/Goノート

{{ . | absURL }}. で配列の値を出力しているので、配列である custom_cssの中身を書き換えればよさそうです。
どこにあるのかと探すと、config.toml にありました。

config.toml

[params]
・・・(中略)・・・
# Include any custom CSS and/or JS files, url or relative to /static folder  
# custom_css = ["css/lightbox.css",   "https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css", "css/main.css"]

custom_cssの部分を以下のように書き換えます。

custom_css = ["css/custom.css"]

すると、ソースにも

<link rel="stylesheet" href="http://localhost:1313/css/custom.css">

と出ます。 サイトを確認すると、custom.cssが読まれていました!

f:id:yokoyoko_115:20200409154218p:plain
日本語フォントになりました。游ゴシック。

localhostとabsURL

head.htmlに戻りまして...

{{ . | absURL }}| absURL の部分が http://localhost:1313/ に相当します。

absURL | Hugo

訳すと、

absURLとrelURLは、サイトのconfigファイルのbaseURLの値から作られます。

となります。
absURLは、 http(s) から始まる「絶対パス」です。
relURLは、/から始まる「 ルートパス」です。

現在のbaseURLはインストール時のままです(テーマ提供元のサイトURLです)。ホスティングする際はここを書き換える必要があります。

今はローカルホストでサイトを表示させているので、baseURLが設定されていてもabsURLはhttp://localhost:1313/ と解釈しているのですね。

***

html/templateのテンプレートの書き方、少しずつ覚えていきたいです。

改行について

改行に手こずりました

phpファイルにて。
やりたかったことは、文字列の特定の箇所で改行することでした。

$text = "あいうえおかきくけこ"

を、ブラウザ上で

あいうえお  
かきくけこ

と表示させたいというものです。

改行させるためには改行コード!

$text = "あいうえお" . "\n" . "かきくけこ"

にすればいいのかと思い、下記の「2バイト文字を含む場合」を参考にさせていただいて書きました。

PHPで文字列の指定した位置に文字列を挿入する方法 - Qiita

preg_replace("/^.{0,5}+\K/us", "\n", $text)

第一引数部分よく分かっていません...!

そしてブラウザで確認すると...

そうです、改行されていませんでした。
使い方を間違えました。

改行コードとは

そもそも\nとは何でしょうか。
「\n、\r = 改行コード」と思っていましたが、違いました。

改行コード - Wikipedia

改行コード とは、ワードプロセッサ(ワープロ専用機)やコンピュータなどで、改行を表す制御文字である。日本では「改行コード」と総称する事が一般的。

制御文字の一種でした。
改行コードはLFCR+LFCRのことをいいます。

名前の由来について詳しく書かれています。

改行コードとそれにまつわるタイプライターのお話 | 株式会社グランフェアズ

タイプライターがかわいい。
CR(キャリッジリターン)=先頭へ戻る
LF(ラインフィード)=行送り
が視覚的によく分かりました。

サクラエディタの改行コードごとの矢印表示も納得です。

ソース上の改行は改行コード

改行コードをソース上で示したものが \n、\r、\r\n という理解で私は落ち着きました。
ここでいう「ソース」とは、Chromeでウェブページを右クリックしたときの「ページのソースを表示」を選択したときのコードです。 「改行コードをソース上で示したもの」は\文字というエスケープシーケンスで表されています。

エスケープシーケンス
ウィキペディア

コンピュータシステムにおいて、通常の文字列では表せない特殊な文字や機能を、規定された特別な文字の並びにより表したもの。

Atomを使っていると忘れがちなのですが、前述したとおり、サクラエディタなどでは、改行のマークとして矢印が表示されます。
それが\n\r\r\nの代わりになっているのではないかと思いました。

「改行」を分けて考える

※色々読み漁ってもズバリな文章を見つけられなかったので半分推測です。

  • enter(return)キー
  • \n\r\r\n
  • <br>

これら3つの改行の働きを整理します。

enter(return)キー

テキストエディタにてenterキーを押すと改行されます。
改行される部分には、目には見えませんが、改行という制御コードが入っていると思われます。

htmlのコードを書いたときのタグの改行はページのソースに反映されます。
テキストの途中で改行させたくてenterキーを押しても、改行が反映されるのはページのソースです。

\n\r\r\n

phpで扱っている文字列などで意図的にソース上の改行をさせたい場合は \n を使います。

使うときは "\n" と、ダブルクォートで囲まないとそのまま文字として出てきてしまいますので注意です。

echo "あいう\nえお";  // OK
echo 'あいう' . "\n" . 'えお';  // OK
echo 'あいう\nえお';  // NG

使い所はソースコードを見やすくできる、ということ以外分かっておりません...。

<br>

ブラウザの表示上で改行させたい場合は <br> を使います。

こちらにまとまっています。
ブラウザで見やすくする!PHPで改行処理を行う方法 | TechAcademyマガジン

便利な nl2br() 関数と pre タグ

改行関連で覚えておきたいものを挙げます。

nl2br()
文字列内の \n\r\r\n<br> に変換するphpの関数です。

$text = "あいう\nえお\nかきくけこ";
echo nl2br($text);

出力結果:

あいう  
えお  
かきくけこ

となります。

preタグ

<pre>-HTML5タグリファレンス

<pre>~</pre>で囲まれた範囲のソースは 半角スペース・改行などがそのまま表示されるため、 <pre>タグは、HTMLソースやプログラムのソースコードをそのまま表示します。

「pre = preformatted text」略で、日本語では「フォーマット(整形)済みのテキスト」という意味らしいので、ソースのまま表示させることができます。

下記のように 配列に対してvar_dump で表示させるときに使うと

$array = ["りんご", "みかん", "もも"];
echo "<pre>"; var_dump($array); echo "</pre>";

出力結果:

array(3) {
  [0]=>
  string(9) "りんご"
  [1]=>
  string(9) "みかん"
  [2]=>
  string(6) "もも"
}

配列が見やすくブラウザに表示されて便利なので無心で使っていました。

このときしか使わない pre タグ...ありがたいです。

デベロッパーツールの「Elements」と「ページのソース」の違い

かねてから少し違うと思っていたのでついでに調べてみました。

Chrome:デベロッパーツールのElementsでは、HTMLの特殊文字は実体参照・コード参照ではなく、実際の字として表示される - Dr.ウーパのコンピュータ備忘録

Chrome のデベロッパーツールの Elements では、Web ページの現在表示している状態の HTML (DOM エレメントツリー)を見ることができます。  
DOMエレメントツリーは、”Web ページの現在表示している状態の HTML”であり、Web ページのソースコードを表示したものとは異なります。

そして、HTMLの特殊文字については、ソースコード実体参照コード参照で書くと、Elemrntsでは、ブラウザに実際に表示されている文字と同じように表示されます。

ソースコード Elements ブラウザ
&#9829
♥(※やってはいけない)

ソースコードに「♥」と書くのはやってはいけない、と言われていますが、問題なく表示されたりするのは、ブラウザが気を利かせて解釈してくれるのでしょうか。
ソースコード実体参照で書くと、Google検索結果のスニペットにも実体参照で出てきたりしたような...。
また別の機会に調べたいと思います。

最後に

同じ境遇の方がいらっしゃいました。嬉しい!

\nで改行できない!【はずがない!】 - Lv1プログラマの誰得メモ

Go言語を学びました

Hugoのサイトを制作する以上、少なくとも知っておいたほうが良いと思い、Progateでレッスンを受けました。(有料会員です!)
学んだときのGo言語の印象をメモします。

PHPとだいたい一緒

phpと文法も似ているように感じました。
...といっても私はプログラミング言語PHPしか触ったことがないので、他の言語との比較ができないのですが、敷居は低い印象を受けました。

以下にPHPと違うところを挙げます。

変数を定義する時にデータ型も定義する

変数を定義する時に同時にデータ型を定義する必要があります。
定義しない場合は自動的に判別されます。

hello := "こんにちは"
var hello string = "こんにちは" と同じ。

:= 便利です。しかもfor文の中で変数定義の際は、:= を使わないとエラーになります。

for i := 1;  i <= 4; i ++ {
  println(i)
} 
// var i int = 1 と書くとエラー。

インポートしたPackageを使わないとエラーになる

Goには標準パッケージという、便利な機能を備えたものがあります。

標準パッケージ 機能
fmt コンソールに出力する
math/rand 乱数を生成する
strings 文字列の連結、置換など
image 画像処理

もっとたくさんあります。

パッケージ - Go 言語

ほとんどよくわからないパッケージばかり...「敷居が低い」は撤回します。

パッケージはインポートして使います。

package main
import "fmt"  // mainパッケージの中で fmt パッケージをインポートする
import "math/rand" // mainパッケージの中で math/rand パッケージをインポートする

func main() {
    fmt.Println("Hello world")    // コンソールに「Hello world」と出力
}

// math/rand パッケージを使っていないのでこのままでは↑の出力もなくエラーが出る。

これはphpと違うと思ったのですがどうなんでしょうか(←自信がなくなっている)。

定義した変数を使わないとエラーになる

package main
func main() {
  a := 100
  b := 200    // 変数bは使われていないためエラー(aの出力もない)
  println(a)
} 

となります。

Progateでは

使っていない変数の存在はバグ(不具合)の原因となることが多いため、Goではエラーを発生させて、バグを未然に防ぐ設計になっています。

とあります。他の言語でもありそうな仕様ですね。

値渡しと参照渡しがわかった

「HugoはGo言語でできているから」で始めたProgateのGo言語ですが、結果、学んだところでHugoがよくわかるようになるというものではありませんでした。

しかし、スライドに出てきた「値渡し」「参照渡し」のおかげで、これまでjavascriptにも出てきたこの考えが少し分かりそうです。

メモリに記録されている変数のアドレス = ポインタ

Go言語ではポインタといいます。

C言語でも出てきます。

プログラム初心者にC言語のポインタを不本意ながら教える羽目になったなら、こう教えると良いよ - 偏見プログラマの語り!

メモリからバイトの話まで、大事そうな部分なので熟読したいところです!
「メモリ空間」は方眼紙をイメージして、その各マス目にバイトが並んでいる...。

バイトの理解も必要ですね。

図にするとこんな感じです。
(Progateのスライドを真似て画像作りました。著作権大丈夫かな)

f:id:yokoyoko_115:20200320033838j:plain

変数はメモリの一部分に登録されていて、変数の住所のように、登録場所である「アドレス(ポインタ)」を持っています。
ポインタはで、16進数で表される事が多いです。
ポインタを変数に格納する際はポインタ型変数に入れて使います。

name := "John"
var namePtr *string = &name  // ↑の画像でいうと 0xc420010230 が入る

ポインタ型変数はデータ型の前に*を付けて定義します。
そして変数のポインタは変数名の前に&を付けると取得できます。

変数の値を出力する方法として、ポインタから操作する方法があります。

fmt.Println(*namePtr)

ポインタを使った変数の値への操作は、ポインタ型変数名の前に*を付けます。

値渡しは変数の値のコピー

関数の引数で変数の値を渡すとき、関数の外で定義した変数は、関数内の変数とは別物です。
↓で変数 a が2つありますが、caluculateスコープの a は、mainスコープの a の値をコピーして代入されたものです。

package main
import "fmt"

func main() {
  a := 1
  calculate(a)
  fmt.Println(a)  // 1のまま。2にはならない
}

func calculate(a int) {
  a += 1  // 2になっている
}

関数の外で定義した変数を関数の中から変更したい場合、ポインタが使えます。

package main
import "fmt"

func main() {
  b := 1
  calculate(&b)  // 変数 b のポインタを引数にする
  fmt.Println(b)  // 2になる
}

func calculate(bPtr *int) {  // ポインタ型変数 bPtr に変数 b のポインタを渡す
  bPtr* += 1  // mainスコープの変数 b の値を更新している
}

ポインタを使えば、スコープを越えてどこからでも変数にアクセスできる、ということでしょうか。
便利な半面、危険なにおいがします。...でもポインタは変数に対して一意な値(おそらく)なので、phpグローバル変数みたいに変数名が被る危険性などは考えずに使えるのでしょうか。
ポインタのベストな使い所はおいおい。

javascriptの場合、オブジェクトは参照型

私がもやもやしていた部分はどこだったか思い出そうと確認したところ、
javascriptの書籍、『javascriptの教科書』にはこう書かれています。

オブジェクトは参照型で、オブジェクト型の値を変数に代入すると、変数にはそのオブジェクへの参照(メモリ上の場所情報)が格納されます。このとき、変数はそのオブジェクトを 参照しているといいます。

...よけいこじらせてしまったかもしれません。
「代入」と「格納」の違いは何でしょうか。

javascriptの場合は、オブジェクトを変数に代入した時点で、メモリ上の場所情報(アドレス)が変数に格納されているようです。

Javascriptでの考え方

少し調べたらとんでもない記事が。
これまで信じてきた常識を覆すタイトルですが、誇張表現ではあると書かれています。

JavaScriptに参照渡し/値渡しなど存在しない - Qiita

「値の参照」腑に落ちました!言葉の定義の問題かなと。

背景:  
 データ型の種類でプリミティブは「値渡し」、オブジェクトは「参照渡し」と言われてきている

・変数に値を代入すると"値の参照"が変数に入る
・変数に値を再代入すると"値の参照"が置き換わる
・変数に変数を代入するとその変数に入ってる"値の参照"が入る

「変数に値を再代入すると"値の参照"が置き換わる」というのがびっくりしました。Go言語では違うのでしょうか。または
ポインタ = 値の参照
ではないかもしれません。

「参照」深いです。
他の言語を学べば、参照について深く考えられそうです。

今回も思いっきり脱線しましたが、他の言語をかいつまんで学ぶのもいいですね。

背景がズレたボタンのアニメーション(css)

疑似要素の扱いがまだまだな今日このごろです。

こちらのページを元に、ボタンを作りました。

https://www.nxworld.net/tips/10-css-cute-design-good-chemistry-button-design-and-hover-effect.html#anchor09
9 . 背景が枠からズレたボタン

このボタンも以前作ったボタン同様、a要素で擬似要素を使っています。 ::after でピンク色部分を絶対配置でずらして、a 要素の後ろに z-index: -1 で配置しています。
hover 時に transition を使って、ずらしたピンク色部分が a 要素の黒枠に収まる、というアニメーションです。

hover 時のアニメーションが変

z-index: -1 のはずなのに、::after要素(ピンク色部分)が a 要素の黒枠の上を通るのです。z-index: -5 など数値を下げても変わりありません。

アニメーション中の状態です↓ f:id:yokoyoko_115:20200319161813p:plain

イメージ↓ f:id:yokoyoko_115:20200320022510j:plain

コードまるまるコピーして使っても、ボタン設置予定場所では変なことになってしまいます。
※codepenではうまくいきました。

z-index: -1 で親要素の後ろにいく

親要素には何の設定もしていません。
背景画像を置いていたので、つまづきました。
png画像で透過させるという、無理矢理で妥協した形で解決)
これは「重ね合わせコンテキスト」を理解すれば説明がつきそうです。

やってみたこと

何とか原因を突き止めて解決できたので、それまでに試したことを挙げます。

アニメーションの条件を変更

:hoverでうまくいかないので、.button.onと、on クラスが付いたときの挙動を確認しました。

→ちゃんと黒い枠線が見えました。

a 要素から span 要素に変更

今度は a タグを疑ってみました。
span 要素を hover したときを検証しました。

→黒い枠線見えました。

ということは、a 要素独自の何かが怪しい...?
最終的にはデベロッパーツールでいろいろチェックを入れたり外したり、試行錯誤しました。

原因は a 要素のopacity

実はcssa:hover { opacity: .8; } と設定しています。
それをなくすと(opacity: 1 でもOK)、謎現象は解消されました。

opacity が作用していたなんて想像つきませんでした。
てっきりz-index とか pointer-events で解決できるのかと。

描画の問題で起こる現象なんでしょうね。

さきほども触れましたが、z-indexの話、どこかの折に重ね合わせコンテキストについておさらいしたいです。

おしまい。