醫學生的K書法:Anki使用心得(下)- 製作卡片模板

鞠雨融(Yvonne Jiu )
20 min readJul 22, 2018

--

“A fountain pen on a spiral notebook” by Aaron Burden on Unsplash

在上篇:醫學生的K書法:Anki使用心得(上)-基礎概念&模版分享中,介紹了Anki的基本概念,本次的下篇,將以實際上製作符合自己需求的卡片為中心,分成三大部分:

  1. 基礎操作:筆記類型(Note Type)的新增與設定
  2. 達成卡片的美觀需求(排版與格式):最高CP值的HTML與CSS
  3. 達成卡片的機能需求:Anki內建語法

基礎操作:筆記類型(Note Type)的新增與設定

點選工具列的「Tools(工具)>Manage Note Types…(管理筆記類型)」,或者按快捷鍵ctrl/command + shift + N就可以叫出Note Types視窗。

點選Add,一個新的視窗會跳出來,問你想要如何新增Note Type,你可以從預設的選項新增Note Type或者是直接複製現存的Note Type。這裡我們用的是預設的Basic(基本型)。點選OK之後他會請你幫新的Note Type命名,這樣就完成新增Note Type的動作了。

回到Anki主畫面,點選「Add…」,從跳出來的視窗上部的「Type」就可以選擇剛才新增的Note Type,接下來,從「Fields…」和「Cards…」這兩個按鈕,我們就可以開始更改這個Note Type的其他詳細設定了。(「Fields…」和「Cards…」這兩個按鈕在Note Type視窗、還有browser中也看到的,也可以從那裡編輯)

點擊「Fields…」按鈕之後,會跳出欄位的設定視窗。在這裡,我們可以新增、刪除、重新命名、排序各個欄位,用法都很直覺應該不必特別說明。

點擊「Cards…」按鈕之後,跳出的則是卡片模板的設定視窗。右上角的「+」符號讓我們可以新增Card(正如上篇介紹的,一則Note可以自動產生多張Card正是Anki的強大之處之一)。而佔了視窗大部分空間的幾個欄位,左半為編輯區,右半為編輯結果的預覽,這篇文章接下來要介紹的事情都發生在這個地方。

值得一提的是,當你新增、刪除Field(欄位)或Card(卡片),總之就是對Note Type進行比較大的修改的時候,如下的警告訊息會跳出,不用慌張,確認你在其他裝置的修改已經有同步,按下yes沒有問題的。(對同步有疑問的話請參考User Manual或上篇提到簡群先生的教學文)。

卡片模板-美觀:最高CP值的HTML & CSS

如同在上篇中提到的,Anki卡片很重要的一個特色是,他將卡片當成網頁來處理,因此自由度相當的高。HTML和CSS是編寫網頁用的程式語言,也正是我們用來編寫Anki卡片的方法。(網路上關於HTML和CSS的資源相當豐富,請參考文末的延伸閱讀。)

如果僅是要排版、格式化Anki卡片,我認為並不需要完整的HTML與CSS知識,有以下這兩項能力就足夠了:

  1. 知道CSS聲明(Declaration)怎麼寫,會使用搜群引擎找到自己需要的CSS屬性(Property)和值(Value)。
  2. 會使用HTML的span, div, class這三個東西。

因此,接下來將以這兩件事情為目標,介紹所謂(在編輯Anki模板上)「最高CP值的HTML與CSS」。如果已經把握、或是打算自己完整學習如何使用HTML和CSS,就請跳過接下來的區塊,直接從「 卡片模板-機能:Anki內建語法」這個部分繼續閱讀吧。

開始之前:註解

程式語言是給電腦讀的命令,而註解則是為了方便人類閱讀以便日後的修改或分享的存在,註解的內容會完全被電腦忽視,對程式本身(在現在的例子中,是最後顯示出來的卡片本身)完全沒有影響。

HTML註解的寫法,是把註解內容包在<!----> 中間:

(下面的例子使用了從外部嵌入的服務,有程式碼套色,可以看出註解的文字顏色比較淺)

CSS的註解寫法則是把註解內容夾在/**/ 之間:

兩者只是使用的符號不同,原理都是一樣的。接下來的教學中,也會使用註解的方式來在程式碼中做解釋。

開始之前:空白鍵與Enter鍵的問題

在上面註解的例子中應該可以發現,換行並不會造成任何影響,這件事情在HTML和CSS全體中都是通用的。在CSS和HTML中,只有「一個空白」在某些時候會有意義(後續會再提到,HTML跟CSS都會使用空白來分隔複數個值),其餘,不管是一百個空白還是按一次enter的換行,都只會被當作「一個空白」來處理。

比如說,在一個HTML編輯器中,不論是輸入:

你 好

還是:


還是:

你                   好

最後顯示出來的東西都是:

你 好

那麼,正式開始吧

在Anki中,HTML會被放在「Front Template」和「Back Template」這兩個格子裡;CSS則被放在「Styling」這個格子裡 — — 請參考下圖,讓我們實際上來看看在Anki中是如何用HTML和CSS來編排卡片的吧。接續上篇,用日文單字卡為例:

除了寫網頁通用的HTML與CSS,在Anki中,用兩個大括弧來代表欄位:

{{欄位名}}

把這樣的語法放在Template(上圖左側最上與最下,也就是放HTML的地方),輸出的卡片(上圖右側)就會在卡片上對應的位置填入該欄位的內容。(比如:{{解釋}}顯示出來是「學生」)

<br>是一個HTML指令,代表的意義是換行(正如在「開始之前:空白鍵與Enter鍵的問題」敘述過的,按enter換行在HTML中沒有效果,只會被顯示成一個空白)

在上圖的例子中,可以看到在Back Template的第一行,{{漢字}}({{假名}})後面有兩個<br>,產生出來的卡片就會像上圖右側那樣,換了兩次行,產生了中間一個空行的空間。

不過,現在這樣的卡片非常不美:我不是很喜歡這個字型,而且覺得置中對齊非常難以閱讀。該怎麼辦呢?這就是CSS該出場的地方了。

讓我們稍微看一下預設的CSS:

.card {
font-family: arial;
font-size: 20px;
text-align: center;
color: black;
background-color: white;
}

只要英文單字認識就可以輕鬆地解讀這段CSS。由上到下,每一行依序代表的意義是「字體:arial」、「字體大小:20點字」、「文字對齊:置中對齊」、「文字顏色:黑色」、「背景顏色:白色」。

在這裡插入一點名詞解釋,請參看下圖:每一行文字是一則CSS聲明(declaration),每條聲明之間必須用半形分號(;)隔開(重要!),每條聲明中,半形冒號前面的是「屬性(property)」而後面的是「值(value)」。

現在,如果我把預設的text-align: center;這一行修改成text-align: left;;並且把font-family: arial;修改成font-family: 源雲明體;(你可以改成任何你電腦裡面有裝的字體)的話:

結果如上圖,文字對齊從置中對齊被改成了靠左對齊,字體也變成源雲明體了。

CSS的語法就是如此簡單,一般文字編輯器有的各種效果都可以輕鬆達成,Google搜尋諸如「css 斜體」「css 行距」,就能找到各種指令的寫法了。對於某項屬性的用法不確定的話,一樣,請教Google大神吧。(關於各種CSS的文字效果,可以查閱下面這兩個頁面,都附有說明與範例:CSS文本CSS字體

到這裡,其實第一項目標已經達成了,CSS聲明的寫法都大同小異,接下來就是勤問Google,可以按照需求無限擴充。下面提供兩個CSS小補充,「顏色」與「背景圖片」。

【附】顏色

前例的「color」和「background-color」這兩個屬性,都是以「顏色」為值。在CSS中指定顏色,有名字和色碼兩大種方法。

有英文名字的顏色,直接打英文CSS都看得懂,可以參考HTML顏色名稱

色碼則包含了十六進制(Hex),rgb,hsl各種,可參考此說明。這邊放上幾個查色碼用的網站:HTML Color CodesHTML顏色選擇器

在這邊介紹一種色碼系統:HSL或HSLA。HSLA四個字母分別代表「色相(Hue)」、「彩度(Saturation)」,「明度(Lightness)」,「透明度(Alpha)」。其中:

  • 色相(H):0~360,色相環上的角度
  • 彩度(S)、明度(L):0%~100%
  • 透明度(A):0~1,0為完全透明,1為完全不透明(用不到的時候透明度這項可以直接省略)

實際使用的寫法像這樣:

background-color: hsl(150, 71%, 75%) /*一個可愛的淺綠色*/color: hsla(160, 50%, 15%, 0.5) /*一個可愛的墨綠色,是半透明的*/

使用這個色碼系統,只要腦子裡面有色相環,嘗試幾次就能很快調到喜歡的顏色,因此是我懶得上網查色碼時最愛用的。

【附】背景圖片

背景的部分,除了可以改顏色以外,還可以使用圖片。

首先,要把想用的圖片放進Anki的資料夾中。在Mac上面,如下圖,選擇「Anki/Preferences…(偏好設定)」(Windows的話則是「Tools(工具)/Preferences…」),在Preferences的視窗跳出後,選擇「Backups(備份)」這個標籤頁,點那行藍色的「Open backup folder」,如下圖:

打開以後會來到這個叫做backups的資料夾中:

往上一層,來到個人檔案1(或者User 1,或者如果你改過個人檔案的名字的話,就是你修改後的名字)這個資料夾,再進入下面的collection.media這個資料夾,這裡就是Anki存放所有跟卡片內容相關的檔案的地方了。

把想要用的圖片檔準備好,放進collection.media資料夾中,接著在CSS區塊的大括弧中加入下面這行指令:

background-image: url(); 
/* 說明:在括弧裡面放該圖片的「檔名.副檔名」。比如本例是url(p0447_l.png) */
大功告成!背景套用了圖片!

關於背景的其他設定,可參考CSS背景

以上,使用HTML指令<br>來換行,然後用可以隨查隨用的簡單CSS指令,已經可以達到一定程度的格式需求了。接下來,我們還可以再進一步。

有沒有注意到我們的CSS指令都被放在一個大括弧裡面,而且這個大括弧前面有著.card這樣的文字呢?

.card扮演的角色是一個「CSS選擇器(selector)」,在這裡,它讓後面的大括弧內的CSS指令被套用到整張卡片上,也就是說,它「選擇」了整張卡片。

只要我們有辦法選擇卡片的某一個部分,我們就可以在不同的地方套用不同的格式了。其實,這就是HTML與CSS最重要的功能:HTML把內容切分成不同區塊,CSS把樣式套用到各個區塊上。

正式進入HTML:span, div, class三個關鍵字

首先,來看看HTML的基本架構。

  • HTML的基本單元是一個元素(Element),每個元素由起始標籤(Opening tag)和結束標籤(Closing tag)把內容夾在中間所構成。在上例中,這個元素是被名叫「span」的標籤包起來,所以會被稱為一個「span元素」
  • 標籤是由小於和大於符號中間夾著標籤名(在此例是span)組成。結束標籤在標籤名之前會多一個\符號;而起始標籤之中,除了標籤名以外,還可以有各種屬性(英文是Attribute,CSS的屬性則是Property,兩者不同),用來做更進一步的設定。

現在,讓我們把卡片Back Template中的「中譯:」和「例句:」像上圖那樣用span 包起來,並且給它們class=”小標題”的屬性。

<span class=”小標題"> 中譯:</span> {{解釋}} <br><span class=”小標題”> 例句:</span> {{例句(日文)}} ({{例句(中文)}})

接著,在Styling部分加上如下的CSS語法:

.小標題 {
font-weight: bold;
}

在英文句號.後面加上特定class的名字,可以讓我們選擇該class。因此,在上面的大括弧中的CSS聲明會被套用在擁有class=“小標題”這個屬性的所有元素上面。實際上的效果看起來就如下圖:

成功用<span>選擇了特定區塊,把他們變成了粗體字!

另外,一個元素可以同時屬於多個不同的class,寫法是用空白分開不同的class名:

<span class=”小標題 highlight”>中譯:</span>

上例中的元素就同時屬於「小標題」和「highlight」這兩個class,利用這個功能可以做一些更複雜的格式設定。例:

同時擁有「小標題」跟「highlight」兩個屬性的元素,既是粗體字,背景色又變成了黃色。

接下來,讓我們試試把上圖中的第一個「span元素」給改成「div元素」:

難解的事情發生了,只是把span改成了div,並沒有在「中譯:」和「{{解釋}}」之間加上換行的<br>,為什麼在卡片上看起來卻像是中間換了一行呢?這就跟spandiv本質上的差異有關了。

span這個標籤,就像我們用滑鼠反白選取一樣,只是單純的選擇,選擇的動作本身不會對內容造成任何影響,但是div就不一樣了。

使用div標籤把內容包起來,其代表的意義是「創造一個箱子,把被包起來的內容塞進這個箱子裡面」。而根據預設值,這個箱子的高度等於內容的高度,寬度則是能多寬就多寬,在這裡,這個箱子就延展到了卡片的寬度,把旁邊的文字給擠了下去,所以看起來就像是換了一行一般。

使用div創造出箱子是非常實用的,利用大小不同的箱子的排列與套疊(把箱子放在箱子裡面),可以做出各種不同的版面配置,而CSS也提供了相關的屬性讓我們客製化這些箱子。

關於CSS盒模型(CSS Box Model)

圖片引自MDN web docs

參考上圖,在客製化我們的div箱子的時候,關於箱子的尺寸,有這些屬性可以使用:

  • width 寬度
  • height 高度
  • border 邊框
  • padding 內距:內容與邊框之間的距離
  • margin 外距:邊框和外界的距離

這些屬性的值(value)都會是長度單位,比如border: 10px;就會產生10px粗的邊框。

其中widthheight這兩個屬性,是盒模型獨有的,而borderpaddingmargin這三個屬性,除了用在盒模型,也可以用在span物件上面。

borderpaddingmargin這三個屬性,又有上下左右四邊,可以分別使用top, right, bottom, left來設定,比如padding-top: 20px; 就只會在上方設定20px寬的padding。

border這個屬性,除了可以設定粗細以外,還可以設定邊框的顏色與線條樣式。(可以參考border-styleborder-radius

這幾個屬性有簡寫的功能,舉例:

/* 例一 */
padding-top: 10px;
padding-right: 11px;
padding-bottom:12px;
padding-left:13px;
/* 上面這四行,跟下面這一行的意思是一模一樣的: */padding: 10px 11px 12px 13px;
/* 簡寫的順序是順時針轉一圈,上、右、下、左 */
/*------------------------*/
/* 例二 */
border-width: 1px;
border-style: dotted;
border-color: red;
/* 上面這四行,跟下面這一行的意思是一模一樣的: */border: 1px dotted red;

複數個值之間都是用空白分隔,和前述HTML的class屬性一樣。

順帶一提,其實整張卡片也是一個箱子(不過並不是div元素就是了,這是沒必要知道的部分)。學到這裡,應該可以了解,其實整張卡片是一個具有class=”card”這個屬性的箱子,所以我們可以用.card選擇器來設定整張卡片的格式。

可以稍微做個實驗,卡片內容跟最外圍會有距離,是有預設的margin存在的緣故。如果在.card的大括弧裡加上一行CSS聲明margin:0;的話,可以看到內容都會緊緊貼著最外圍:

整張卡片也是一個箱子,有margin屬性。

應用div和這幾個屬性,我們可以對這張卡片做許許多多非常細緻的設定了,下面提供我做的示範,並且在程式碼中以註解的方式加上說明,可以當作前文介紹的所有東西的一個總複習。

接下來的程式碼,請跟下面這張圖片參看:

範例HTML(Back Template):

範例CSS:

以上,就是針對編輯Anki模板,最高CP值的HTML與CSS的介紹,只需要掌握CSS基礎和div,span, class,就可以滿足絕大多數的格式與排版需求囉。

卡片模板-機能:Anki內建語法

除了前面介紹的,以兩個大括弧包起的{{欄位}}以外,Anki還有其他內建的特殊語法可以幫助我們達成更多樣化的功能:

在預設的「基本型(Basic)」Note Type中被使用到的兩個特殊語法:

  • {{FrontSide}}:是一個特殊欄位,只能用在Back Template上面,代表所有放在Front Template上面的東西。
  • <hr id=answer>:插入一條橫向分隔線。

滿足練習的拼字的需求:{{type:}} 語法

寫法:{{type:欄位名}}

這個東西必須同時出現在Front Template和Back Template上面才能正常作用(放在Front Template上,然後再Back Template上面放{{FrontSide}}這個欄位也是行得通的)。放在卡片正面的{{type:欄位名}}會顯示一個輸入框,讓我們可以輸入答案;然後在背面的則幫我們比對我們輸入的答案和「欄位名」這個欄位的內容,給出結果。

這在語言學習上練習拼字,或者學習某些外文專有名詞,要記得拼法的時候非常實用。再次以日文單字卡為例,我在以漢字為正面的卡片上面加上{{type:假名}}來測試自己能不能輸入該漢字正確的讀法。

記得{{type:}}欄位必須在正面背面都放上才能正常作用!

使用的結果如上圖所示,在卡片的正面會出現輸入欄位,如果我輸入的答案有錯,在背面Anki會替我指正。

兩個條件變數語法

  • {{#欄位A}} 如果名為「欄位A」的欄位是空的,那麼這段被包在這個中間的東西將不會被顯示 {{/欄位A}}
  • {{^欄位A}} 除非名為「欄位A」的欄位是空的,否則這段被包在這個中間的東西將不會被顯示 {{/欄位A}}

如同上述說明,可以根據某欄位中內容的有無來決定要不要顯示某些內容。這兩個語法應用的範圍非常廣:

例一、作為功能開關:

{{type:}} 可以測試用來拼字的能力,但是或許有些字拼法太過簡單,根本沒必要特別練習,這時可以新增一個欄位(在此例中命名為「拼字on/off」),使用條件變數來做調整:

{{#拼字on/off}} {{type:假名}} {{/拼字on/off}}
<!-- 說明:在「拼字on/off」這個欄位內沒有東西的時候, {{type:假名}} 會被忽略 -->

如此,在有測試拼字需求的時候,在「拼字on/off」欄位中填入任意內容,反之則讓該欄位保持空的狀態,可以當作功能開關來使用。

例二、隱藏空白欄位的項目:

假設有幾則Note的某些欄位為空,此時並不希望在卡片上這個欄位的小標題被顯示出來,舉例如下:

舉例:「織田信長」這個單字根本不需要中文翻譯,只需要測試漢字跟片假名就夠了,但是「中譯:」這個小標題還是存在。(上篇複習:Anki只會產生「正面不為空白」的Card,因此這則Note只會產生正面為漢字的Card1和正面為漢字的Card2,正面為解釋的Card3不會被產生出來~)

這時,可以用條件變數來解決這個問題,把背面的HTML如下修改:

結果如下圖:

上面兩例都使用了{{#欄位A}} {{/欄位A}} 這個語法(「欄位A」內有東西的時候才顯示);而{{^欄位A}} {{/欄位A}} (「欄位A」內有東西的時候不顯示)只是功能相反,應用方法同理。

尾聲

以上,是在Anki中編輯卡片模板的方法。除了這篇教學文,我另外準備了一份Cheat Sheet,將在編輯卡片模板時常用的參考資料與連結整理了一下,有需要歡迎參考。

(2018/08/06更新:在這裡,順便分享本文中使用的範例單字卡的模板→點我下載。歡迎有需要的讀者自行取用~)

參考資料&延伸閱讀:

CSS與HTML的教學:我覺得MDN Web Docs的教學寫得非常清楚易懂。不過中文化似乎還有些不完全,而且還只有簡體字,因此在此還是先附上英文版連結。要轉換語言的話請點標題右側「Languages」按鈕喔!

W3School的教學,雖然不及MDN Web Docs但是有繁體中文(雖然翻譯還是有點怪,且每篇教學末尾最實用的表格並沒有被中文化到)

任何的問題、回饋、心得都歡迎留言反應。如果你喜歡這篇文章,拍手、轉發對我言都是最大的鼓勵。感謝你的閱讀!

--

--