Typst小ネタ集

# Appendix関数を作る 
Appendix関数を以下のように作ったうえで，show ruleを用いる．
```rust
#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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787163/4e013a37-b4e0-b3c1-a7d0-bcd9dc13df3d.png)


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

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

```rust

#Appendix[
= new section
]

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


```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787163/176b5399-326f-1107-99f2-761dc0dbdc64.png)

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

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

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

具体的には以下のようにしている．
```rust
//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) ={
        context{
        let  eql = counter("auto-numbering-eq" + str(tlabel))
        if eql.final().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を適用すればよい．具体的には以下の通りである．

```rust
#show ref: it => eq_refstyle(it)
```

その後，以下のようにすれば，参照された数式にのみ，番号がつく．
```rust
#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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787163/71e35995-f304-b004-f523-9da36bf193c6.png)

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

```rust
#aeq("label3",name:"G1")[
  $
  lim inf f
  $
]
 @label3.
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787163/ed3e5430-2de7-1ce0-dab4-e5c894a566f0.png)

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

方法としては次の通り．
1. 複数形の辞書を用意する（plurals_dic）
1. refsを作成する．なお，separatorとしてandやcommaなどを設定できるようにする（定理1 or 2みたいなものにも対応可能にする）．
   
以下がその実装例である．
```rust
//複数形の辞書
#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を取得する．