How to Format the Transition Elements in the Periodic Table

#let table_edge = 1pt + black
#let table_in_edge = 0.5pt + black
#let template(heading_numbering_top: "§ 1.1", quote-lrspace: 2em, doc) = {
  set text(lang: "cn")
  // 文档模板

  // 文档编号

  // 标题
  //  #set heading(numbering: "1.")
  //#let fig = counter("figure")
  //#let tab = counter("table")
  //
  //#let fig_numbering(.., desc) = {
  //  fig.step()
  //  context str(counter(heading).get().at(0)) + "-" + context //fig.display()
  //}
  //
  //#let tab_numbering(.., desc) = {
  //  tab.step()
  //  context str(counter(heading).get().at(0)) + "-" + context //tab.display()
  //}
  //
  //#show figure.where(
  //  kind: table
  //): set figure.caption(position: top)

  // 字体
  set text(font: ("Noto Serif CJK SC"))
  show math.equation: set text(font: ("New Computer Modern Math", "Noto Serif CJK SC")) //"New Computer Modern Math", 

  // 排版
  set table(
    
    stroke: (bottom: 0.5pt + black, right: 0.5pt + black),
  )
  // 3线表
  set table(
    align: (center + horizon),
    stroke: (x, y) => {
      if x != 0 { (left: table_in_edge) }
      (top: table_in_edge)
    },
    inset: 0.7em,)
  show table: it => {
    if table.hline(stroke: table_edge) in it.children {
      return it
    }
    let children = it.children
    let new_children = ()
    for i in children {
      new_children += (i,)
      if repr(i).starts-with("header") {
        new_children += (table.hline(stroke: table_edge),)
      }
    }
    let meta = it.fields()
    meta.remove("children")
    return table(..meta, table.hline(stroke: table_edge), ..new_children, table.hline(stroke: table_edge))
  }
  show table: it => {
    // 居中
    align(center, block(width: 100%, it))
  }

  doc
}
#show: template
#set page(flipped: true, margin: 1em)
#let nonmetal_colour = green
#let noble_gases_colour = purple
#let metallic_element = blue
#let elements_block(
  number,
  name,
  name_cn,
  name_latin,
  relmass,
  valence,
  type,
) = {
  box(
    height: 4em,
    width: 40pt,
    fill: if type == 0 { nonmetal_colour } else if type == 1 { noble_gases_colour } else if type == 2 {
      metallic_element
    } else { none },
    outset: 0.1pt,
    stroke: none,
    grid(
      columns: 1,
      row-gutter: 0.5pt,
      block(height: 0.5pt),
      box(height: 0.7em)[#h(0.2em)#number#h(1fr)#name#h(0.2em)],
      box(height: 1em)[#align(center, [#text(size: 0.7em, name_cn)#v(-0.8em)#text(size: 0.4em, name_latin)])],
      box(height: 1em)[#v(0.2em)#align(center, text(size: 0.7em, str(relmass)))],
      box(height: 1.5em)[#v(0.1em)#set text(size: (24 - 12 / valence.len()) / (valence.len()) * 1pt);#valence.join(
          ",",
        )],
    ),
  )
}
#let electron_layer = ("Q", "P", "O", "N", "M", "L", "K")
#let number_of_electrons_in_group_18_elements = (32, 18, 8, 2)
#let elements_table_end3(n) = {
  let o1 = (electron_layer.at(-1),)
  for i in electron_layer.slice(electron_layer.len() - n) {
    o1 = (i, ..o1)
  }
  let _ = o1.pop()
  let o2_t = if n <= 3 { (8, 8, 2).slice(3 - n) } else {
    (8, 18) + number_of_electrons_in_group_18_elements.slice(number_of_electrons_in_group_18_elements.len() + 2 - n)
  }
  let o2 = (o2_t.at(-1),)
  for i in o2_t {
    o2 = (i, ..o2)
  }
  let _ = o2.pop()
  o1 = o1.map(x => [#v(0.1em)#text(size: 0.7em, x)])
  o2 = o2.map(x => [#v(0.1em)#text(size: 0.7em, [#str(x)])])
  (
    table.cell(align(bottom, stack(dir: btt, ..o1) + v(0.2em))),
    table.cell(align(bottom, stack(dir: btt, ..o2) + v(0.2em))),
    //table.hline(),
    [#(n + 1)],
  )
}

#let elements_table = figure({
  let number_inset = 5pt
  table(
    columns: 21,
    inset: 0pt,
    align: center + horizon,
    stroke: (x,y) => {
      if x > 2 and x < 13 and y == 4 {
        (top: 3pt + red)
      } else if x == 3 and y >3 and y < 9 {
        (left: 3pt + red)
      }
    },
    table.header(
      [],
      table.vline(),
      ..range(1, 19)
        .map(str)
        .map(strong)
        .map(x => {
          v(number_inset)
          h(number_inset)
          x
          h(number_inset)
          v(number_inset)
        }),
      table.vline(),
      [#{
          v(number_inset)
          h(number_inset)
        }*#text(size: 0.5em, "电子层")*#{
          h(number_inset)
          v(number_inset)
        }],
      table.vline(),
      [#{
          v(number_inset)
          h(number_inset)
        }*#text(size: 0.5em, "O族电子数")*#{
          h(number_inset)
          v(number_inset)
        }],
    ),
    [1],
    elements_block(1, "H", "氢", "Hydrogenium", 1, ("+1", "-1"), 0),
    table.cell(colspan: 16, []),
    elements_block(2, "He", "氦", "Helium", 4, ("0",), 1),
    ..elements_table_end3(1),
    elements_block(3, "Li", "锂", "Lithium", 7, ("+1",), 2),
    elements_block(4, "Be", "铍", "Beryllium", 9, ("+2",), 2),
    table.cell(colspan: 10)[],
    elements_block(5, "B", "硼", "Borum", 11, ("+3",), 0),
    elements_block(6, "C", "碳", "Carbonium", 12, ("+2", "+4", "-4"), 0),
    elements_block(7, "N", "氮", "Nitrogenium", 14, ("-3", "+2", "+3", "+4", "+5"), 0),
    elements_block(8, "O", "氧", "Oxygenium", 16, ("-2",), 0),
    elements_block(9, "F", "氟", "Fluorum", 19, ("-1",), 0),
    elements_block(10, "Ne", "氖", "Neon", 20, ("0",), 1),
    ..elements_table_end3(2),
    elements_block(11, "Na", "钠", "Natrium", 23, ("+1",), 2),
    elements_block(12, "Mg", "镁", "Magnesium", 24, ("+2",), 2),
    table.cell(colspan: 10)[],
    elements_block(13, "Al", "铝", "Aluminium", 27, ("+3",), 2),
    elements_block(14, "Si", "硅", "Silicium", 28, ("+4", "-4"), 0),
    elements_block(15, "P", "磷", "Phosphorum", 31, ("-3", "+3", "+5"), 0),
    elements_block(16, "S", "硫", "Sulphur", 32, ("-2", "+4", "+6"), 0),
    elements_block(17, "Cl", "氯", "Chlorum", 35.5, ("-1", "+1", "+3", "+5", "+7"), 0),
    elements_block(18, "Ar", "氩", "Argon", 40, ("0",), 1),
    ..elements_table_end3(3),
    elements_block(19, "K", "钾", "Kalium", 39, ("+1",), 2),
    elements_block(20, "Ca", "钙", "Calcium", 40, ("+2",), 2),
    elements_block(21, "Sc", "钪", "Scandium", 45, ("+3",), 2),
    elements_block(22, "Ti", "钛", "Titanium", 48, ("+2", "+3", "+4"), 2),
    elements_block(23, "V", "钒", "Vanadium", 51, ("+2", "+3", "+4", "+5"), 2),
    elements_block(24, "Cr", "铬", "Chromium", 52, ("+2", "+3", "+6"), 2),
    elements_block(25, "Mn", "锰", "Manganum", 55, ("+2", "+4", "+6", "+7"), 2),
    elements_block(26, "Fe", "铁", "Ferrum", 56, ("+2", "+3"), 2),
    elements_block(27, "Co", "钴", "Cobaltum", 59, ("+2", "+3"), 2),
    elements_block(28, "Ni", "镍", "Niccolum", 59, ("+2", "+3"), 2),
    elements_block(29, "Cu", "铜", "Cuprum", 64, ("+1", "+2"), 2),
    elements_block(30, "Zn", "锌", "Zincum", 65, ("+2",), 2),
    elements_block(31, "Ga", "镓", "Gallium", 70, ("+3",), 2),
    elements_block(32, "Ge", "锗", "Germanium", 73, ("+2", "+4"), 0),
    elements_block(33, "As", "砷", "Arsenicum", 75, ("-3", "+3", "+5"), 0),
    elements_block(34, "Se", "硒", "Selenium", 79, ("-2", "+4", "+6"), 0),
    elements_block(35, "Br", "溴", "Bromum", 80, ("-1", "+1", "+5", "+7"), 0),
    elements_block(36, "Kr", "氪", "Krypton", 84, ("0",), 1),
    ..elements_table_end3(4),
    elements_block(37, "Rb", "铷", "Rubidium", 85, ("+1",), 2),
    elements_block(38, "Sr", "锶", "Strontium", 88, ("+2",), 2),
    elements_block(39, "Y", "钇", "Yttrium", 89, ("+3",), 2),
    elements_block(40, "Zr", "锆", "Zirconium", 91, ("+4",), 2),
    elements_block(41, "Nb", "铌", "Niobium", 93, ("+3", "+5"), 2),
    elements_block(42, "Mo", "钼", "Molybdenum", 96, ("+2", "+3", "+4", "+5", "+6"), 2),
    elements_block(43, "Tc", "锝", "Technetium", 98, ("+4", "+6", "+7"), 2),
    elements_block(44, "Ru", "钌", "Ruthenium", 101, ("+2", "+3", "+4", "+6", "+8"), 2),
    elements_block(45, "Rh", "铑", "Rhodium", 103, ("+2", "+3", "+4"), 2),
    elements_block(46, "Pd", "钯", "Palladium", 106, ("+2", "+4"), 2),
    elements_block(47, "Ag", "银", "Argentum", 108, ("+1",), 2),
    elements_block(48, "Cd", "镉", "Cadmium", 112, ("+2",), 2),
    elements_block(49, "In", "铟", "Indium", 115, ("+3",), 2),
    elements_block(50, "Sn", "锡", "Stannum", 119, ("+2", "+4"), 2),
    elements_block(51, "Sb", "锑", "Stibium", 122, ("-3", "+3", "+5"), 0),
    elements_block(52, "Te", "碲", "Tellurium", 128, ("-2", "+4", "+6"), 0),
    elements_block(53, "I", "碘", "Iodum", 127, ("-1", "+1", "+5", "+7"), 0),
    elements_block(54, "Xe", "氙", "Xenon", 131, ("0",), 1),
    ..elements_table_end3(5),
    elements_block(55, "Cs", "铯", "Caesium", 133, ("+1",), 2),
    elements_block(56, "Ba", "钡", "Barium", 137, ("+2",), 2),
    [$57~71$],
    elements_block(72, "Hf", "铪", "Hafnium", 178, ("+4",), 2),
    elements_block(73, "Ta", "钽", "Tantalum", 181, ("+5",), 2),
    elements_block(74, "W", "钨", "Wolframium", 184, ("+6", "+4", "+2"), 2),
    elements_block(75, "Re", "铼", "Rhenium", 186, ("+7", "+4", "+2", "-1"), 2),
    elements_block(76, "Os", "锇", "Osmium", 190, ("+4", "+3", "+2"), 2),
    elements_block(77, "Ir", "铱", "Iridium", 192, ("+4", "+3"), 2),
    elements_block(78, "Pt", "铂", "Platinum", 195, ("+4", "+2"), 2),
    elements_block(79, "Au", "金", "Aurum", 197, ("+3", "+1"), 2),
    elements_block(80, "Hg", "汞", "Hydrargyrum", 201, ("+2", "+1"), 2),
    elements_block(81, "Tl", "铊", "Thallium", 204, ("+3", "+1"), 2),
    elements_block(82, "Pb", "铅", "Plumbum", 207, ("+4", "+2"), 2),
    elements_block(83, "Bi", "铋", "Bismuthum", 209, ("+3", "+5"), 2),
    elements_block(84, "Po", "钋", "Polonium", 209, ("+4", "+2"), 2),
    elements_block(85, "At", "砹", "Astatium", 210, ("+7", "+5", "+3", "+1", "-1"), 0),
    elements_block(86, "Rn", "氡", "Radon", 222, ("+2",), 1),
    ..elements_table_end3(6),
    elements_block(87, "Fr", "钫", "Francium", 223, ("+1",), 2),
    elements_block(88, "Ra", "镭", "Radium", 226, ("+2",), 2),
    //elements_block(104, "Rf", "𬬻", "Rutherfordium", 267, ("+4",), 2),
    //elements_block(105, "Db", "𬭊", "Dubnium", 268, ("+5",), 2),
    //elements_block(106, "Sg", "𬭳", "Seaborgium", 269, ("+6",), 2),
    //elements_block(107, "Bh", "𬭛", "Bohrium", 270, ("+7",), 2),
    //elements_block(108, "Hs", "𬭶", "Hassium", 270, ("+8",), 2),
    //elements_block(109, "Mt", "鿏", "Meitnerium", 278, ("+9", "+8", "+6", "+4", "+3", "+1"), 2),
    //elements_block(110, "Ds", "𫟼", "Darmstadtium", 281, ("+8", "+6", "+4", "+2", "0"), 2),
    //elements_block(111, "Rg", "𬬭", "Roentgenium", 282, ("+5", "+3", "+1", "-1"), 2),
    //elements_block(112, "Cn", "鎶", "Copernicium", 285, ("+2", "+1", "0"), 2),
    //elements_block(113, "Nh", "鉨", "Nihonium", 286, ("+1",), 2),
    //elements_block(114, "Fl", "鈇", "Flerovium", 289, ("+2",), 2),
    //elements_block(115, "Mc", "镆", "Moscovium", 290, ("+1",), 2),
    //elements_block(116, "Lv", "鉝", "Livermorium", 293, ("+2",), 2),
    //elements_block(117, "Ts", "钿", "Tennessine", 294, ("+1",), 0),
    //elements_block(118, "Og", "鿫", "Oganesson", 294, ("+1",), 1),
  )
})

#elements_table

I want a read block to around the Transition Elements to mark them like this:

I would have a look at: pinit – Typst Universe

Also it is not published yet but you may find it useful: ptable-amat:0.1.0 by GiggleLiu · Pull Request #3910 · typst/packages · GitHub

Hi @LRoInT ,

in addition to the answer of @vmartel08, you could also just use the table to do this. For this you just need to create a few table.hline and table.vline elements. In your case, just append this four lines to your table:

#table(
   ..,
    table.vline(x: 3, stroke: red, start: 4, end: 7),
    table.vline(x: 13, stroke: red, start: 4, end: 7),
    table.hline(y: 4, stroke: red, start: 3, end: 13),
    table.hline(y: 7, stroke: red, start: 3, end: 13),
)

and set table.stroke to none.

Now you will observe the the lines are partially hidden by the cells. This is because the content (you used block to wrap each cell content) is drawn on top of the table lines. But the fill of a table.cell would actually drawn behind the table lines.

Therefore, I suggest you swap out the outer wrapping block for table.cell in your function elements_block. Here you will need to replace some of the arguments to block

  • width: instead specify table.columns with the desired width
  • height: instead specify table.rows with the desired width
  • outset: instead use table.inset.
4 Likes