置頂介紹文

這裡主要放一些關於數學和 LaTeX 的文章, 文章內的檔案一律用 xelatex 編譯而成。
如果你想下載我的 tex 檔回去修改編譯, 請將 preamble.7z 解壓縮後和 tex 檔放在同一個資料夾中即可編譯。
部落格內的文章也有部份是網路或書籍中的資料經過統整編輯而成, 如有侵權請告知。
有任何問題也歡迎留言或 E-mail 給我。

2016年12月11日 星期日

LaTeX 自訂指令 (command) 基礎篇

LaTeX 裡有一大堆的指令, 不過用久了還是覺得不夠用或是常用的一直輸入很煩, 所以我們來談談如何自訂指令 (又或者稱為巨集指令)。

雖然在本文中我們用指令一詞, 不過事實上這就是巨集 (macro) 了, 只是好像一看到巨集大家都會覺得是高端使用者的玩意兒, 事實上在 LaTeX 裡, 巨集指令是相當常用, 也是用 LaTeX 的人一定要學會的技能。

先來定義一個新的指令 (command), 如下例, 我們可以把常用的字串包在一起成為一個新的指令, 那麼將來只要輸入這個指令就可以了。

......
\newcommand{\stuinf}{\hfill 班級:\underline{\hspace{2cm}}座號:\underline{\hspace{1cm}}姓名:\underline{\hspace{3cm}} \\}

\begin{document}

\stuinf

\end{document}

不過只是這樣還不夠, 我們希望能定義出像 LaTeX 一樣能輸入其他文字 (也就是帶有參數) 的指令, 如下例:

......
\newcommand{\by}[1]{\hfill【#1】}

\begin{document}

這可能是一個考題。\by{108學測}

\end{document}

接在新指令後的 [1] 表示可以"必須"有一個大括號, 對應到指令裡的 #1, 如果想要更多的變量, 可以這麼做:

......
\newcommand{\testtitle}[3]{臺北市立麥斯高中 #1學年度第#2學期數學科#考卷}

\begin{document}

\testtitle{105}{2}{期末}

\end{document}

有時候我們不想要每次都輸入所有的參數, 可以選擇性的輸入(未輸入的參數就留白或忽略); 又希望未輸入時, 參數能有預設值, 輸入後又能改變參數, 那麼我們再來看最後這個例子:

......
\newlength{\fillspace}
\setlength{\fillspace}{1cm}
\newcommand{\exf}[2][]{\underline{\hspace{#1\fillspace}#2}}
\newcommand{\exff}[2][3.5]{\underline{\hspace{#1\fillspace}#2}}

\begin{document}

\exf{test1}

\exf[2]{test1}

\exff{test2}

\exff[4.5]{test2}

\end{document}

我在這個例子裡定義了一個長度 (length), 有機會再另外談。另外我定義了兩個新的指令, \exf, \exff, 這兩個指令在 [2] 之後都還有另一個 [], 用來表示第一個參數 #1 為選擇性輸入(要輸入時需用中括號), \exf 的 [] 裡沒有任何預設值, 而 \exff 的 [3.5] 則表示未輸入參數時就自動代入參數 3.5, 來看看結果是什麼:


結果分別是留白底線 1cm, 2cm, 3.5cm 和 4.5cm。

要自訂指令有兩點需要注意的是, 第一, 新的指令不能是 LaTeX 裡已經有的指令; 第二, 在 LaTeX 裡, 大小寫指的是不同的指令, 可以善加利用。

2016年12月10日 星期六

LaTeX 好用套件 (package) - catchfilebetweentags

這個套件的名稱實在非常直白 (笑), 用途就是在一個 tex 檔中取出某一段文字, 用來合併檔案十分方便。

在這裡我們有三個文件, 分別是 00.tex, 01.tex 和 02.tex, 我們要在 01.tex 和 02.tex 中取出一段文字放在 00.tex 裡。

% 00.tex

......

\usepackage{catchfilebetweentags}

\begin{document}

這個文件可以先有一些文字

\ExecuteMetaData[01]{mytaga}

\ExecuteMetaData[02]{mytagb}

\end{document}

接下來是 01.tex

% 01.tex

......

\begin{document}

%<*mytaga>
這是會被取走的文字 text part1....
%</mytaga>

\end{document}

然後是 02.tex

% 02.tex

......

\begin{document}

%<*mytagb>
這也是會被取走的文字 text part2....
%</mytagb>

\end{document}

那麼編譯 00.tex 就會出現這樣的結果:


這個套件的優點是, 原本把檔案合併只能用 \input 把整個檔案放到另一檔案中, 但用這個套件可以保證每個檔案都是可以獨立編譯的檔案, 然後如果需要合併則只取文字部份合併即可。

一個小缺點就是這個套件可以合併編譯出 PDF 檔, 但是對原始檔案文字沒有合併的功能。

2016年11月24日 星期四

LaTeX 免費編輯器 Texmaker

鑑於 Miktex 的原生編輯器 Texworks 真的很陽春, 對初學者不是很友善,, 對老手也有一些地方不方便, 所以我花了時間研究了較多人推薦的 Texmaker, 真的很好用喔, 來試試吧。

先列一些 Texmaker 的優點
  1. 有數學輸入的按鈕: 這對初學者很重要, 忘記語法時可以直接找到, 當然常用的最後還是背起來比較方便。
  2. 有指令輸入快速完成: 特別用在很長的指令如 \includegraphics, 只要輸入前幾個單字很按 Enter 就會出現 \includegraphics[scale=•]{•} 了。 
  3. 左列會將 \section 各自編列為大綱, 點選就會跳到該節, 方便找到檔案的位置
  4. 會把引入的外部檔案 (\input, \include) 標示出來, 點選後可以直接開啟, 這對檔案的編修非常的有用喔
  5. 可以收起整節或整個環境的文字段落, 保持版面的清爽
這麼方便的編輯器, 因為不是原生編輯器, 所以我們需要加入一些設定, 以下是用可攜的 (Portable) MikTeX 和可攜的 Texmaker 來設定:
  1. 檔案放置的位置: 先要有一個資料夾 (LaTeX), 在這之中開一個資料夾 (MikTeX), 在 MikTeX 裡放入 MikTeX 和 Texmaker 可攜檔的資料夾 (miktex_portable, texmakerwin32usb)
  2. 把要編譯的檔案用一資料夾打包 (xelatex_work) 放在和剛剛的 MikTeX 同一層
  3. 然後去 texmakerwin32usb 資料夾裡找到 texmaker.exe , 按右鍵將其設為桌面捷徑, 再把這個桌面捷徑剪下放在 LaTeX 裡 (和 xelatex_work 同層), 以後開檔案都要先點這個捷徑, 建議可以放在工作列的快速選單中
接下來, 要在 Texmaker 裡設定編譯的方式, 我們這麼設定為 xelatex 編譯, 方法如下:
  1. 點選 [選項] → [設定 Texmaker]
  2. 首先要修改編譯的方式為 xelatex, 所以要把 [命令] 中 LaTeX 的欄位改為 xelatex -interaction=nonstopmode %.tex 
  3. 必須把 xelatex 欄位修改為相對路徑 "../miktex_portable/miktex/bin/latexmk.exe" -e "$pdflatex=q/pdflatex -synctex=1 -interaction=nonstopmode/" -pdf %.tex 
  4. 把快速編譯選為 XeLaTeX + View PDF, 之後只要按 [F1] 就會用 xelatex 編譯了
  5. 到編輯器裡將字型編碼設定為 UTF-8
這樣所有的設定都完成了, 要開啟檔案的話, 先點選剛剛建立的捷徑 (如果有放到工作列就很方便), 然後按 Ctrl+O 開檔案, Texmaker 會自動記得你的資料夾, 用修改日期排序的話就能快速找到檔案了

2016年10月3日 星期一

LaTeX 表格設計

從 Word 轉移到 LaTeX 的過程中, 就屬表格和插入圖片最難以掌握, 因為似乎總不能隨心所欲的想怎樣就怎樣, 不過學會之後, 會發現 LaTeX 的表格很好掌握喔!

這篇會把所有表格常用的語法, 包括基本表格 (tabular) 環境, 表格內水平置中 (center), 垂直置中, 表格手動內換行 (break line) 以及 設定表格樣式 (newcolumntype) 的語法一併說明。

\documentclass[12pt]{article}

\usepackage[CJKnumber]{xeCJK} %讓中英文字體分開設置
\setCJKmainfont[BoldFont={cwTeX Q Hei Bold}]{cwTeX Q Ming Medium} % 設預設中文字型及預設粗體

\usepackage[a4paper, margin=1.5cm]{geometry}%設定紙張及邊界
\renewcommand{\baselinestretch}{1.4}%設定行距{倍數}

\usepackage{tabularx, array, slashbox}%表格
\usepackage{makecell} %表格內換行
\usepackage{multirow}
\renewcommand{\multirowsetup}{\centering} %合併表格後, 內容水平置中

\newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}}
\newcolumntype{M}[1]{>{\centering\arraybackslash}m{#1}}
\newcolumntype{B}[1]{>{\centering\arraybackslash}b{#1}}

\begin{document}

\begin{tabular}{|c|p{0.2\textwidth}|p{5cm}|P{0.3\linewidth}|}
\hline
1-1 & 1-2 & 1-3 & 1-4 \\
\hline
2-1& 這是很多字的第二欄, 所以他會自動換行, 一直換一直換一直換......... & 2-3 \par 第一種手動換行 \par 2-3 & \makecell[t]{2-4 \\ 第二種手動換行 \\ 2-4} \\
\hline
3-1 & \multicolumn{2}{c|}{\makecell[t]{雙欄合併 \\ 換行要用 makecell}} & 3-4 \\
\hline
4-1 & \multicolumn{1}{c|}{單格水平置中} & \multicolumn{1}{r|}{單格水平靠右} & 4-4 \\
\hline
5-1 & \multirow{4}{\linewidth}{垂直置中} & 5-3 & \mbox{} \vspace*{2cm} \\
\hline
\end{tabular}


\end{document}

在 tabular 環境中先設定參數, c 表示該欄均水平置中, p{}表示表格頂端對齊, 大括號內則是欄寬, 可以是絕對長度 (5cm), 也可以是相對長度 (0.2\textwidth)。而在 c 和 p 這兩個表格樣式 (columnstyle) 之間用 | 可以畫出表格的鉛直線。

因為每一欄只能有一種表格樣式 (columnstyle), 用 c 置中就無法再用 p 來設定寬度, 反之亦然, 因此若要置中同時設定表格寬度, 就必須先在宣告區定義
\newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}}, 那麼 LaTeX 會在每一欄一開始加入 \centering\arraybackslash 來讓內容水平置中。

由於表格環境裡已經用 \\ 來表示換列, 所以表格單格內換行必須用 \par 或是 \makecell 來處理。\par 可用在一般的換行, 但是有些地方會行不通; \makecell 則是相當的泛用, 其中參數 [t] 是用來設定為頂端對齊, 若用 [c] 則是中間對齊。

若需要雙欄合併可用 \multicolumn 語法, 第一個指令為合併欄數, 第二個指令為合併後水平對齊方式, c 為置中, r 為置右, 第三欄則為表格內文字。也因為 \multicolumn 可以重新定義水平對齊方式, 所以我們可以用合併"一欄" 的語法來讓單欄表格內容水平置中或水平靠右。

若需要設定表格列高則在末欄加上 \vspace 即可, 如果末欄沒有文字時需要用 \mbox{} 假裝文字。

設定了表格列高後, 如希望文字垂直置中, 則用 \multirow 語法, 第一欄為列數, 用來調整文字位置, 第二欄為欄寬, 用 \linewidth 表示與現在欄寬一致, 第三欄為表格內文字。又因為我在宣告區設定了 \renewcommand{\multirowsetup}{\centering}, 所以內容會呈現水平置中, 此設定預設值為靠左 (\raggedright), 如果希望靠右, 則設定為 \renewcommand{\multirowsetup}{\raggedleft} 即可。

在 LaTeX 或是較正式的排版中, 我們不建議用表格來達成排版的目的, 表格主要還是運用於資料的整理及傳達, 而排版應該在文章中讓 LaTeX 自行計算即可。一旦這樣來理解表格, 那麼 LaTeX 的表格不僅更能表現出我們要的效果, 並且在設定好之後完全沒有格式跑掉的疑慮, 其方便性體驗過就能明白了。

article_latex表格基本功.tex
article_latex表格基本功.pdf

2016年7月12日 星期二

用 LaTeX 做數學考卷 (六) : 答案卷與解答篇 -- 文字標籤與解答對應

很重要所以寫在最上面, 用了 label 和 ref,  要編譯兩次文章才會正常顯示喔!

上一篇我們學會了用 iffalse 的語法來編譯出不同的檔案 - 顯示或不顯示解答, 但這些解答都還是在答案卷裡, 一旦改變題序或增刪題目就會全數重做, 即使複製貼上也是要花許多工夫。

因此這篇要來介紹利用 label 和 ref 的功能, 用文字對應的方式, 只要先設定好答案卷格式, 解答直接寫在題目上, 就可以編譯出純題目卷、含解答的題目卷、空白答案卷以及含解答的答案卷四種卷子, 非常好用, 趕快來學。

因為這篇文章幾乎結合了之前的所有語法, 所以語法的理解需要花較多的時間, 若有不懂, 歡迎留言討論。

先介紹 text label 的用法。

一般而言, label 和 ref 大都用在圖、表和文章章節上, 而在這裡, 因為我們想將寫在文章中的某段文字, 重複在文章的其他地方顯示, 並且即使這段文字經過修改, 其他地方的文字也會顯示修改後的最新文字, 我們將此稱為 text label。


......
\usepackage[colorlinks=true, linkcolor=black]{hyperref}

\makeatletter
\newcommand{\textlabel}[2]{%
\protected@write \@auxout {}{\string \newlabel {#1}{{#2}{\thepage}{#2}{#1}{}}}%
\hypertarget{#1}{#2}}

\makeatother
......

\begin{document}

\textlabel{foo}{這段文字想放在哪, 就放在哪}

\ref{foo}

\end{document}


\usepackage[colorlinks=true, linkcolor=black]{hyperref} 這個套件是在 label 和 ref 之間在編譯出來的 PDF 檔上加入超連結, 如果不用的話必須修改 \makeatletter 的整段語法, 有興趣可以留言跟我拿。

語法看不太懂沒關係, 只要知道 \textlabel 的用法是 \textlabel{標籤}{文字}就可以了。要顯示的地方只要加上 \ref{標籤} 即可。

行文至此, 我們可以想像, 在題目卷打上答案之後, 可以把答案直接用 ref 放到答案卷的表格中。而題目卷上的答案和答案卷表格中的答案都可以利用 iffalse 來決定是否要顯示。

這裡衍生出另一個問題是: 如果每個答案都要手動標籤 (label) 再手動對應 (ref), 那麼一旦改變題序, 就要再手動調整, 因此我們結合計數器, 讓 latex 幫我們在每個解答上按著順序自動編上標籤, 並且自動對應到答案卷的表格中。

接下來的語法需結合前面所有的語法, 所以請直接下載範例檔來研究, 這裡只解釋自動編號的做法。


......
%填充題答案, 直接在格子中填入 \ansfis 即可
\newcounter{fillans}\setcounter{fillans}{1}
\newcommand{\ansfis}{\ansis{\ref{fill\thefillans}}\stepcounter{fillans}}

%題目卷上的答案 用\onlyquestiontrue顯示題目卷, 反之顯示答案
\newif\ifonlyquestion

\usepackage[colorlinks=true, linkcolor=black]{hyperref}%

%填充題解答與標籤(自動) \ansf{<answer>} (放在要填入的位置上) 要有hyperref套件
\newcounter{filllabel}\setcounter{filllabel}{1}
\makeatletter
\newcommand{\ansf}[1]{%
\ifonlyquestion
\protected@write \@auxout {}{\string \newlabel {fill\thefilllabel}{{#1}{\thepage}{#1}{fill\thefilllabel}{}}}%
\hypertarget{fill\thefilllabel}{\ansfill} \stepcounter{filllabel}
\else
\protected@write \@auxout {}{\string \newlabel {fill\thefilllabel}{{#1}{\thepage}{#1}{f\thefilllabel}{}}}%
\hypertarget{fill\thefilllabel}{\underline{\hspace{0.2cm}{\bf\boldmath{#1}}\hspace{0.2cm}}} \stepcounter{filllabel}
\fi }

\makeatother
......

\begin{document}
\showanswertrue
\onlyquestiontrue

\題目卷上的題目與答案
\begin{enumerate}

\item 令 $F$ 是抛物線 $\Gamma$: $y^2=4cx$ 的焦點, $A$、$B$ 是 $\Gamma$ 上相異兩點且 $A$、$B$、$F$三點共線。若 $\overline{AF}=8$、$\overline{BF}=6$, 則 $c=$\ansf{$\pm\frac{24}{7}$}。

\item 已知 $P$ 點為雙曲線 $\frac{x^2}{4}-\frac{y^2}{3}=1$ 上的任意點, $F_1$, $F_2$ 為此雙曲線的兩焦點, 若 $\triangle PF_1F_2$ 恰為等腰三角形, 則 $\triangle PF_1F_2$ 的周長為\ansf{$6\sqrt{7}\pm4$}。

\item 設圓 $C$: $(x+4)^2+y^2=16$, 則通過點 $A(2,0)$且與圓 $C$ 相切之圓的圓心所形成的圖形方程式為\ansf{$\frac{(x+1)^2}{4}-\frac{y^2}{5}=1$}。

\item 設 $P$ 為橢圓$\frac{x^2}{16}+\frac{y^2}{9}=1$上一動點, 則當 $(x,y)=$\ansf{$\left(\frac{16}{5}, \frac{9}{5}\right)$} 時, $x+y$ 有最大值\ansf{$5$}。

\end{enumerate}

%答案卷的表格
\begin{tabularx}{\linewidth}{|X|X|X|X|X|}
\hline
(\no) \ansfis &(\no) \ansfis &(\no) \ansfis \rowvs\\
\hline
(\no) \ansfis &(\no) \ansfis &\blank \rowvs\\
\hline
\end{tabularx}

\end{document}


我設定了一個 \ifonlyquestion 來控制題目卷是否顯示解答, 這樣能和答案卷是否顯示解答分開控制, 如果不想分開, 改成之前的 \ifshowanswer 即可。

\newcounter{filllabel}\setcounter{filllabel}{1} 設定新的計數器 filllabel。

{fill\thefilllabel} 這裡的語法就是標籤, 會依 \ansf 的順序自動以 {fill1}{fill2}{fill3}...設定標籤。

\newcounter{fillans}\setcounter{fillans}{1} 設定答案卷 ref 要用的計數器。
\newcommand{\ansfis}{\ansis{\ref{fill\thefillans}}\stepcounter{fillans}} 用 ref 將剛剛的 label 顯示出來。

上述都是填充題的標籤, 因為在題目卷上的解答格式不同, 我把選擇題和填充題的計數器及標籤分開設定。

如範例所示, 題目和答案在打字時直接寫在一起即可。另外只要在答案卷的表格中, 每個打上 \ansfis 就可以了顯示答案了。也就是說, 答案卷只要算好格子, 其他的語法完全不用變動就可以自動編譯出答案卷了。

article_用latex做數學考卷6-3.tex
article_用latex做數學考卷6-3(純題目與空白卷).pdf
article_用latex做數學考卷6-3(題目和含解答的答案卷).pdf
article_用latex做數學考卷6-3(含解答的題目卷和答案卷).pdf

用 LaTeX 做數學考卷 (六) : 答案卷與解答篇 -- iffalse 邏輯判斷

答案卷通常有兩個需要, 一是空白讓學生考試用的, 二是有答案讓老師改考卷用的。我們不想在兩個不同的檔案中畫出同樣的表格, 再把其中一個檔案填入答案, 因為這樣一來, 若題目有增刪, 同一個動作要再做兩次。因此, 我們要用 iffalse 控制 latex 是否印出答案來。

先學 iffalse 的語法

......
\newif\ifshowanswer
......

\begin{document}

\showanswertrue

\ifshowanswer
  A: 如果用 showanswertrue 就顯示這行
\else
  B: 如果用 showanswerfalse 或是都不加, 就顯示這行
\fi

\end{document}



\newif\ifshowanswer 設定新的 if 指令

\showanswertrue 在文章開頭加入這行, 就會顯示出A行, 否則顯示B行。

語法很簡單, 不過因為我們需要的是不印出答案時是只有格子或編號的樣式, 並且要不斷重複使用, 所以我們打包它。

......
\usepackage{multicol}
\usepackage{multirow}
\renewcommand{\multirowsetup}{\centering} %合併表格後, 內容水平且垂直置中
\renewcommand\arraystretch{1.2}%調整表格內行高

\newif\ifshowanswer

\newcommand{\ansis}[1]{
\ifshowanswer
\multirow{3}{\linewidth} {\large #1}
\else
\multirow{3}{\linewidth} {\mbox{}}
\fi }
......

\begin{document}

\showanswertrue

\begin{enumerate}

\item 填充題

%\hspace{-1cm}
\begin{tabularx}{\linewidth}{|X|X|X|X|X|}
\hline
\no. \ansis{ABC} &\no. \ansis{$\frac{3}{2}$} &\no. \ansis{$3$} \vspace*{1.5cm} \\
\hline
\no. \ansis{$2\pi$} &\no. \ansis{$\sqrt[3]{5}$} &\mbox{} \ansis{\mbox{}} \vspace*{1.5cm} \\
\hline
\end{tabularx}

\end{enumerate}

\end{document}


\usepackage{multicol}
\usepackage{multirow}
\renewcommand{\multirowsetup}{\centering} %合併表格後, 內容水平且垂直置中
\renewcommand\arraystretch{1.2}%調整表格內行高

這四行調整表格設定, 為了將答案在表格內水平並垂直置中, 我們要用合併表格的方式處理。

\multirow{3}{\linewidth} {\large #1} 合併表格的語法是 \multirow{列數}{表格寬度}{文字}, \large 用來把文字放大。表格中就用 \ansis{答案} 來填入解答。

所以, \showanswertrue 就會顯示答案, \showanswerfalse 就是顯示空格。

範例檔只是要讓各位看到差別所以複製了兩個同樣的內容, 實際使用當然只要寫一次就可以囉。

article_用latex做數學考卷6-2.tex
article_用latex做數學考卷6-2.pdf

2016年7月11日 星期一

用 LaTeX 做數學考卷 (六) : 答案卷與解答篇 -- 空白答案卷

用 LaTeX 做數學考卷的最後一個系列 - 答案卷篇, 這篇一樣會分成三小篇:
  1. 用表格 tabularx 製作空白答案卷
  2. 用 iffalse 製作答案卷中是否顯示答案 (空白或解答版)
  3. 用 label 和 ref 把寫在題目後的解答連結到答案卷中
首先是製作空白答案卷:

......
\usepackage{tabularx}

\newcommand{\vs}{\vspace*{1.8cm}}

\begin{document}
\testtitle{臺北市立麥斯高級中學104學年度第1學期數學科期末考答案卷}

\begin{enumerate}

\item 複選題

\hspace{-1cm}
\begin{tabularx}{\textwidth}{|X|X|X|X|X|}
\hline
\no. &\no. &\no. &\no. \vs \\
\hline
\no. &\no. &\no. &\no. \vs \\
\hline
\end{tabularx}

\setcounter{nocounter}{1}
\item 填充題

%\hspace{-1cm}
\begin{tabularx}{\linewidth}{|X|X|X|X|X|}
\hline
(\no) &(\no) &(\no) \vs \\
\hline
(\no) &(\no) &(\no) \vs \\
\hline
(\no) &(\no) &(\no) \vs \\
\hline
(\no) & &\mbox{} \vs \\
\hline
\end{tabularx}


\end{enumerate}
\end{document}


\newcommand{\vs}{\vspace*{1.8cm}} 定義新指令, 方便把表格的列高固定及統一調整。

\begin{tabularx}{\textwidth}{|X|X|X|X|X|} 開始表格環境, |X| 定義表格平均分配欄寬, \textwidth 定義表格總寬度為整頁的內文長度。而填充題用的 \linewidth 則是所在行的文字長度, 兩者有一些不同喔。

\hspace{-1cm} 把表格左移 1cm

\hline 畫橫線

\no. &\no. &\no. &\no. \vs \\ 用 & 來分欄, 用 \\ 來分列, 每列末欄加入 \vs 使其行高變成定義的 1.8cm, 如果末欄為空格, 則需用 \mbox{} 來假裝有文字才能使 \vspace 有作用。

article_用latex做數學考卷6-1.tex
article_用latex做數學考卷6-1.pdf