You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Typst Polylux主题获取颜色变量报错,请求排查原因

问题排查:Typst Polylux主题标题页背景颜色错误

问题场景

我正在使用Typst开发一个简单的Polylux主题(代码保存为sorbonne-slides.typ),核心代码如下:

#import "@preview/polylux:0.3.1": *

// Color definitions
#let sorbonne-blue = rgb("#1D2769")
#let sorbonne-red = rgb("#AC182E")
#let sorbonne-lightblue = rgb("#52B5E5")
#let sorbonne-yellow = rgb("#FFB700")
#let sorbonne-text = rgb("#263068")

// Primary background color
#let primary-color = state("faculty-color", none)

#let sorbonne-theme(
  aspect-ratio: "16-9", 
  fontsize: 3em,
  faculty: none,
  body) = {

  set page(
    paper: "presentation-" + aspect-ratio,
  )

  set text(font: "Fira Sans", size: fontsize, fill: sorbonne-text)
  
  // update primary color according to variable 'faculty'
  if faculty == "sante" {
    primary-color.update(sorbonne-red)
  } else if faculty == "sciences" {
    primary-color.update(sorbonne-lightblue)
  } else if faculty == "lettres" {
    primary-color.update(sorbonne-yellow)
  } else {
    primary-color.update(sorbonne-blue)
  }
  
  body
}

// title-slide 
#let title-slide(
  title: [], 
  subtitle: [],
  author: [], 
  date: [], 
  location: []
  ) = {

    // background of the title slide
    let background = context primary-color.get()
    set page (
      fill: background,
    )

    set text(
      fill: white, 
      size: 35pt
    )
  
    grid(
      columns: auto, 
      rows: (0.60fr, 0.40fr), 
      row-gutter: 1em,
      align(horizon)[
        #strong(title)
        #parbreak()
        #strong(text(size: .7em,  subtitle))
      ],
      align(top)[
        #text(size: .7em, author)
        #parbreak()
        #text(size: .7em, location)
        #parbreak()
        #text(size: .7em, date)
      ] 
    )    
  }

调用主题生成标题页的代码:

#import "sorbonne-slides.typ": *

#show: sorbonne-theme.with(aspect-ratio: "16-9", faculty: "sante")

#title-slide(
  title: [A funny title], 
  subtitle: [A funny subtitle],
  author: [A funny author],
  date: [2024-03-18], 
  location: [A funny department], 
)

运行后出现错误:

error: expected color, gradient, pattern, or none, found content
   ┌─ \\?\C:\Users\3121805\Dropbox\programmes\polylux templates\sorbonne-slides-typst\sorbonne-slides.typ:45:12
   │
45 │       fill: background,
   │             ^^^^^^^^^^

help: error occurred in this call of function `title-slide`

错误原因

let background = context primary-color.get()这一行是问题核心:context关键字会将primary-color.get()返回的颜色值包装成内容类型(content),而set page(fill: ...)要求传入的是颜色、渐变、图案或none类型,两者类型不匹配,因此触发报错。

state的get()方法本身返回的是原始值(此处为颜色),但用context包裹后,会把这个值转换为可渲染的内容对象,不再是纯颜色类型。

修复方案

只需去掉context关键字,直接获取state的原始值即可:

修改后的title-slide函数

// title-slide 
#let title-slide(
  title: [], 
  subtitle: [],
  author: [], 
  date: [], 
  location: []
  ) = {

    // 直接获取state的原始颜色值
    let background = primary-color.get()
    set page (
      fill: background,
    )

    set text(
      fill: white, 
      size: 35pt
    )
  
    grid(
      columns: auto, 
      rows: (0.60fr, 0.40fr), 
      row-gutter: 1em,
      align(horizon)[
        #strong(title)
        #parbreak()
        #strong(text(size: .7em,  subtitle))
      ],
      align(top)[
        #text(size: .7em, author)
        #parbreak()
        #text(size: .7em, location)
        #parbreak()
        #text(size: .7em, date)
      ] 
    )    
  }

更简洁的写法

也可以直接在set page的fill参数中调用primary-color.get(),省去变量定义:

set page (
  fill: primary-color.get(),
)

原理说明

primary-color是全局状态变量,在sorbonne-theme函数中已经根据faculty参数更新为对应的颜色值。title-slide执行时,直接调用get()就能获取到原始的颜色类型值,不需要context——context仅用于将值转换为可渲染的内容,而此处我们需要的是纯颜色类型,用于设置页面背景填充。

内容的提问来源于stack exchange,提问作者eusebe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 23:54:57