5
1

Typst小ネタ集

Last updated at Posted at 2024-05-10

Appendix関数を作る

Appendix関数を以下のように作ったうえで,show ruleを用いる.

#set heading(numbering:"1.1.")

#let Appendix(body, name:"Appendix", numbering: "A.1.", newpage:false) = {
  if newpage == true {
  pagebreak()
  }
  counter(heading).update(0)
  set heading(numbering: numbering)
  align(center)[#text(size: 2.0em)[#name]]
  body
}

= ordinal section

#show: Appendix

= appendix section

すると以下のような形になる.
image.png

show 関数名: としたときには,それ以下の行をbodyとして扱うと考えればよい.

もちろん,以下のようにして,Appendixの範囲を限定することができる


#Appendix[
= new section
]

#Appendix(name:"Supplementary Materials", numbering: "I.1.")[
= new section
]


image.png

式を引用したときだけ数式番号をつける

つまり,$\LaTeX$でいう,autonumパッケージのようなことをしたい.

やり方としては

  1. 参照されたときにその数式専用のカウンターを生成するようにref関数を書き換える関数を作成する(eq_refstyle).
  2. 生成したカウンターを更新し,その値が文章末までに1になっていれば,番号付きの数式を,そうでなければ番号なしの数式を返す関数(auto-numbering-equation)を作成する.

具体的には以下のようにしている.

//autonumbering equations

#let numb_style(tag,tlabel,name,numbering:"(1)") = {
 if tag == true or name != none {
   if name == none{
   return  it => "("+str(tlabel)+")"}
   else {return it => "("+str(name)+")"}
 }
 else {
   return  numbering
 } 
}

#let tell_labels(it) ={
  if type(it) == "label"{return it}
  else {return label(str(it))} 
}

#let auto-numbering-equation(tlabel, name:none, tag:false,numbering:"(1)", body) ={
        locate(loc =>{
        let  eql = counter("auto-numbering-eq" + str(tlabel))
        if eql.final(loc).at(0) == 1{
          [#math.equation(numbering: numb_style(tag,tlabel,name,numbering:numbering),block: true)[#body]#tell_labels(tlabel)]
         if tag == true{counter(math.equation).update(i => i - 1)}
          }
        
        else {
         [#math.equation(numbering:none,block: true)[#body] ]
        }
      })
}

//shorthand
#let aeq = auto-numbering-equation


#let eq_refstyle(it) = {
  return  {
  let lbl = it.target
  let eq = math.equation
  let el = it.element
  let eql = counter("auto-numbering-eq"+str(lbl))
  eql.update(1)
  if el != none and el.func() == eq {
      link(lbl)[
      #numbering(
        el.numbering,
        ..counter(eq).at(el.location())
      ) ]
  } 
    else {it}
  }
}

その後,show ruleを使って,ref関数を書き換える.テンプレートでこれをしたいときには,project関数のところで,show ruleを適用すればよい.具体的には以下の通りである.

#show ref: it => eq_refstyle(it)

その後,以下のようにすれば,参照された数式にのみ,番号がつく.

#aeq("label1")[
  $
  sum_(i=1)^oo 1/i
  $
]

#aeq("label2")[
  $
  integral_(1)^oo 1/x dif x
  $
]

The first equation, @label1 is referred. The second equation is not reffered.

image.png

なお,数式番号だけではなく,以下のようにタグをつけることも可能である.

#aeq("label3",name:"G1")[
  $
  lim inf f
  $
]
 @label3.

image.png

複数の定理や表などを参照する

#refs(label1,label2,label3)と言った感じでTables 1, 2, and 4のように複数の定理や表を参照したい.

方法としては次の通り.

  1. 複数形の辞書を用意する(plurals_dic)
  2. refsを作成する.なお,separatorとしてandやcommaなどを設定できるようにする(定理1 or 2みたいなものにも対応可能にする).

以下がその実装例である.

//複数形の辞書
#let plurals_dic = ("Proposition": "Propositions", 
                    "Theorem":"Theorems", 
                    "Lemma":"Lemmata",
                    "Definition":"Definitions", 
                    "Table":"Tables",
                    "Assumption":"Assumptions",
                    "Figure":"Figures", 
                    "Example": "Examples",
                    "Fact":"Facts")

//単数形に対して辞書を参照したうえで複数形を与える関数.
#let plurals(single,dict) ={
  if single in dict.keys() {
    return dict.at(single)
  } else {return single}
}




#let refs(..sink,dict:plurals_dic,add:" and ",comma:", ") = {
  let args = sink.pos()
  let numargs = args.len()
  let current_titles = ()
  let titles_dic = (:)
  if numargs == 1 {link(ref(args.at(0)).target)[#ref(args.at(0))]}
  else {
  show ref: it => plurals(it.element.supplement.text,dict)
  ref(args.at(0)) + " "
  show ref: it => {
     let c_eq = it.element.counter
      numbering(it.element.numbering,
      ..c_eq.at(it.element.location()))
  }
  if numargs == 2 {link(ref(args.at(0)).target)[#ref(args.at(0))] + ""+ add +"" + link(ref(args.at(1)).target)[#ref(args.at(1))]}
  else{
  for i in range(numargs){
   if i< numargs - 1 {link(ref(args.at(i)).target)[#ref(args.at(i))] + comma+"" }
   else {add+"" + link(ref(args.at(i)).target)[#ref(args.at(i))]}
  }}
  }
}
  • 単数,双数で若干扱いが異なるので場合分けをしている.
  • ..sinkの部分は可変な数の引数.この部分を参照するラベルのリストとする.sink.pos()で引数のarrayを取得する.
5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1