Skip to content

Commit a3d7c53

Browse files
Merge pull request typst-doc-cn#27 from YDX-2147483647/more
docs: citation form, auto hanging indent, cjk-latin space at `\ `
2 parents b59a028 + 16248b8 commit a3d7c53

File tree

10 files changed

+282
-30
lines changed

10 files changed

+282
-30
lines changed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ A simple typst example.
5858

5959
👀 shown as the source, but 🛑 not executed in the preview.
6060

61-
#### Limitations
61+
#### Limitations and caveats
6262

6363
Simple examples are evaluated in a container and their states are shared across the entire document.
6464

@@ -72,9 +72,13 @@ As a result:
7272

7373
- Citations and bibliographies will conflict with other examples.
7474

75+
- The default configuration values are those specified in `raw`, which may differ from the defaults in regular documents.
76+
77+
For example, the default `text.cjk-latin-spacing` is typically `auto`, but here it is `none`.
78+
7579
-
7680

77-
If you need advanced features, please write a page example instead.
81+
If you require advanced features or 100% accuracy, please write a page example instead.
7882

7983
### Page examples (`example-page`)
8084

main.typ

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
#import "typ/util.typ": babel, bbl, issue, note, prompt, pull, unichar, workaround
1+
#import "typ/packages/till-next.typ": mark-till-next, till-next
2+
#import "typ/util.typ": babel, bbl, issue, note, now-fixed, prompt, pull, unichar, workaround
23
#import "typ/prioritization.typ": level, level-table
3-
#import "typ/show-example.typ": render-examples
4+
#import "typ/show-example.typ": layout-git-log, render-examples
45
#show: render-examples
56

67
#babel(en: [Chinese Layout Gap Analysis for Typst.], zh: [分析 Typst 与中文排版的差距。])
@@ -44,6 +45,7 @@
4445

4546
#set heading(numbering: "1.1")
4647
#show heading.where(level: 3): set heading(numbering: none)
48+
#show: mark-till-next
4749

4850
= #bbl(en: [Text direction], zh: [文本方向])
4951

@@ -677,7 +679,7 @@
677679
```
678680

679681
```example-page
680-
>>> // This example behaves differently in `example` and `example-page`.
682+
>>> // This example behaves differently in `example` and `example-page` because of cjk-latin-spacing.
681683
>>> #set text(top-edge: "ascender", bottom-edge: "descender")
682684
>>> Current:
683685
#set par(justify: true)
@@ -816,6 +818,25 @@ $ integral f dif x $
816818
>>> 汉字#h(0.25em)$A$#h(0.25em)汉字
817819
```
818820

821+
=== #bbl(en: [Redundant CJK-Latin space at manual line breaks], zh: [人为换行时多余中西间距])
822+
823+
#level.advanced
824+
#issue("typst#6539")
825+
826+
#babel(
827+
en: [If the line is manually broken between a CJK and a Latin character, then typst will insert an extra CJK-Latin space. This space becomes noticeable when text is aligned to the right or center.],
828+
zh: [若在汉字和拉丁字母间手动换行,typst 会插入多余中西间距。如果文本右对齐或居中对齐,这个间距会显现出来。],
829+
)
830+
831+
```example
832+
>>> Current: \
833+
#set text(cjk-latin-spacing: auto)
834+
#box(width: 3em, stroke: (right: green), align(right, [国国\ TT]))
835+
836+
>>> Expected: \
837+
>>> #box(width: 3em, stroke: (right: green), align(right, [国国TT]))
838+
```
839+
819840
=== #bbl(en: [Punctuation compression is interrupted by `#show`], zh: [`#show`会打断标点挤压])
820841

821842
#level.basic
@@ -957,6 +978,31 @@ $ integral f dif x $
957978
>>> = 一、标题
958979
```
959980

981+
=== #bbl(en: [The auto hanging indents of multiline headings are inaccurate], zh: [多行标题的自动悬挂缩进不准确])
982+
983+
#level.advanced
984+
#issue("typst#6527")
985+
#workaround("https://github.com/typst/typst/issues/6527#issuecomment-3026200835")
986+
987+
#babel(
988+
en: [The default value of `heading.hanging-indent` is `auto`, which indicates that the subsequent heading lines will be indented based on the width of the numbering. However, the `auto` width is not accurate if the numbering ends with a full-width punctuation, e.g., #unichar("").],
989+
zh: [`heading.hanging-indent`默认为`auto`,表示标题从第二行起按编号的宽度缩进。然而若编号以全宽标点结尾,例如 #unichar(""),那么`auto`得出的宽度并不准确。],
990+
)
991+
992+
```example-page
993+
#set page(width: 5 * 12pt + 2 * 1em, margin: 1em)
994+
#show heading: set text(12pt)
995+
996+
>>> #show heading: pad.with(top: -0.75em)
997+
>>> Current:
998+
#set heading(numbering: "一、")
999+
= 寻寻觅觅
1000+
1001+
>>> Expected:
1002+
>>> #set heading(numbering: none, hanging-indent: 2em)
1003+
>>> = 一、寻寻觅觅
1004+
```
1005+
9601006
== Styling initials <initials>
9611007

9621008
#prompt(from-w3c: "https://www.w3.org/TR/clreq-gap/#initials")[
@@ -1137,13 +1183,15 @@ $ integral f dif x $
11371183

11381184
=== #bbl(en: [Citation numbers are flying over their brackets], zh: [引用编号的数字高于括号])
11391185

1140-
#level.basic
1141-
#issue("typst#633")
1186+
#level.ok
1187+
#issue("typst#633", closed: true)
11421188
#issue("typst#6513", closed: true)
11431189
#issue("typst#4203", closed: true)
1144-
#pull("typst#5777")
1190+
#pull("typst#5777", merged: true)
11451191
#workaround("https://typst-doc-cn.github.io/guide/FAQ/cite-flying.html")
11461192

1193+
#till-next(now-fixed.with(last-affected: "0.13.1", last-level: "basic"))
1194+
11471195
#babel(
11481196
en: [The style `gb-7714-2015-numeric` formats a citation with a number enclosed in square brackets (e.g., `[1]`) and render them in superscript. However, some fonts only provide dedicated superscript glyphs for numbers, not for brackets. This can cause misalignment, with the numbers appearing higher than the brackets in the superscript.],
11491197
zh: [`gb-7714-2015-numeric`样式会用括号包裹引用编号(例:`[1]`)并上标。不过有些字体只给数字提供了专用上标版本,而括号未提供。这导致上标时未对齐,数字显得比括号高。],
@@ -1232,7 +1280,7 @@ $ integral f dif x $
12321280

12331281
````example-page
12341282
>>> Expected: \
1235-
<<< 孔乙己@key,另见文献~#parencite(<key>)。
1283+
<<< 孔乙己@key,另见#cite(<key>, form: "prose-short")。
12361284
>>> 孔乙己#super[[1]],另见文献#h(0.25em)#[[1]]。
12371285
````
12381286

@@ -1600,6 +1648,8 @@ $ integral f dif x $
16001648
[
16011649
- #bbl(en: [Document version], zh: [文档版本]) \
16021650
#link(git.commit_url)[commit #git.name] (#link(git.log_url)[log])
1651+
1652+
#layout-git-log(summary: bbl(en: [Latest log], zh: [最新日志]), git.latest_log)
16031653
]
16041654
}
16051655

netlify.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ bash scripts/patch-htmldiff.sh
2020
[[headers]]
2121
for = "/assets/*"
2222
[headers.values]
23-
Access-Control-Allow-Origin = "https://services.w3.org" # Allow CORS for /htmldiff
23+
Access-Control-Allow-Origin = "*" # Allow CORS for https://services.w3.org/htmldiff
2424

2525

2626
[[plugins]]

scripts/build.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,51 @@ import { fileURLToPath } from "node:url";
44
import { extraArgs } from "./config.ts";
55
import { precompile } from "./precompile.ts";
66
import { typst } from "./typst.ts";
7-
import { duration_fmt } from "./util.ts";
7+
import { duration_fmt, execFile } from "./util.ts";
8+
9+
interface GitInfo {
10+
name: string;
11+
commit_url: string;
12+
log_url: string;
13+
/** latest git log */
14+
latest_log: string;
15+
}
16+
17+
async function git_info(): Promise<GitInfo | null> {
18+
const git_log = execFile("git", [
19+
"log",
20+
"--max-count=1",
21+
"--pretty=fuller",
22+
"--date=iso",
23+
]).then(({ stdout }) => stdout.trim());
824

9-
function git_info(): string[] {
1025
if (env.GITHUB_ACTIONS === "true") {
1126
// https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
1227
const base = `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}`;
13-
const info = {
14-
name: `${env.GITHUB_SHA?.slice(0, 8)} (${env.GITHUB_REF})`,
28+
return {
29+
name: `${env.GITHUB_SHA?.slice(0, 8)} (${env.GITHUB_REF_NAME})`,
1530
commit_url: `${base}/commit/${env.GITHUB_SHA}`,
1631
log_url: `${base}/actions/runs/${env.GITHUB_RUN_ID}`,
32+
latest_log: await git_log,
1733
};
18-
return ["--input", `git=${JSON.stringify(info)}`];
1934
} else if (env.NETLIFY === "true") {
2035
// https://docs.netlify.com/configure-builds/environment-variables/
21-
const info = {
36+
return {
2237
name: `${env.COMMIT_REF?.slice(0, 8)} (${env.HEAD})`,
2338
commit_url: `${env.REPOSITORY_URL}/commit/${env.COMMIT_REF}`,
2439
log_url:
2540
`https://app.netlify.com/sites/${env.SITE_NAME}/deploys/${env.DEPLOY_ID}`,
41+
latest_log: await git_log,
2642
};
27-
return ["--input", `git=${JSON.stringify(info)}`];
2843
} else {
29-
return [];
44+
return null;
3045
}
3146
}
3247

48+
function as_input(info: GitInfo | null): string[] {
49+
return info ? ["--input", `git=${JSON.stringify(info)}`] : [];
50+
}
51+
3352
if (process.argv[1] === fileURLToPath(import.meta.url)) {
3453
await precompile();
3554

@@ -38,7 +57,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
3857
"compile",
3958
"index.typ",
4059
"dist/index.html",
41-
...git_info(),
60+
...as_input(await git_info()),
4261
...extraArgs.build,
4362
]);
4463
console.log(

scripts/config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ export const extraArgs = {
2323
"mode=build",
2424
"--input",
2525
`x-url-base=${
26-
env.NETLIFY === "true" ? "/" : (env.GITHUB_PAGES_BASE ?? "/clreq/")
26+
env.NETLIFY === "true"
27+
? env.DEPLOY_URL + "/" // patch htmldiff, or assets will go to services.w3.org
28+
: (env.GITHUB_PAGES_BASE ?? "/clreq/")
2729
}`,
2830
...envArgs,
2931
],

scripts/patch-htmldiff.sh

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@ set -euxo pipefail
99
# The commit version might be the following:
1010
# https://github.com/w3c/htmldiff-ui/blob/5eac9b073c66b24422df613a537da2ec2f97f457/htmldiff.pl
1111

12-
# Set base.
13-
# Otherwise, CSS & JS will go to services.w3.org.
14-
#
15-
# This CGI-mode feature is missing in CLI mode.
16-
# https://github.com/w3c/htmldiff-ui/blob/5eac9b073c66b24422df613a537da2ec2f97f457/htmldiff.pl#L560-L563
17-
if [[ "${NETLIFY:-false}" == "true" ]]; then
18-
sd --fixed-strings "<head>" "<head><base href='$DEPLOY_URL/'>" dist/index.html
19-
fi
2012

2113
# Improve readability for `<pre>`.
2214
#

src/util.css

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,44 @@ aside.note {
4444
color: var(--accent);
4545
}
4646
}
47+
48+
/* `details.now-fixed` */
49+
details.now-fixed {
50+
margin-block: 1em;
51+
border-left: 3px solid var(--accent);
52+
border-radius: 8px;
53+
padding-inline-start: 1.5em;
54+
padding-block: 0.5em;
55+
56+
> summary {
57+
cursor: pointer;
58+
margin-left: -0.5em;
59+
60+
display: grid;
61+
grid-template-columns: auto 1fr;
62+
align-items: center;
63+
64+
font-weight: bold;
65+
color: var(--accent);
66+
67+
/* Replace ::marker with ::before */
68+
list-style: none;
69+
70+
&::before {
71+
display: block;
72+
height: 2em;
73+
width: 2em;
74+
}
75+
76+
> p {
77+
margin-top: 0;
78+
}
79+
}
80+
81+
> summary::before {
82+
content: "▶";
83+
}
84+
&[open] > summary::before {
85+
content: "▼";
86+
}
87+
}

typ/packages/till-next.typ

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/// Apply a function to the following content until next heading or `#till-next`.
2+
///
3+
/// = Usage
4+
///
5+
/// == Input
6+
///
7+
/// ```
8+
/// #show: mark-till-next
9+
///
10+
/// A
11+
///
12+
/// #till-next(wrapper)
13+
///
14+
/// B
15+
///
16+
/// C
17+
///
18+
/// = Heading
19+
///
20+
/// D
21+
/// ```
22+
///
23+
/// == Equivalent output
24+
///
25+
/// ```
26+
/// A
27+
///
28+
/// #wrapper[
29+
/// B
30+
///
31+
/// C
32+
/// ]
33+
///
34+
/// = Heading
35+
///
36+
/// D
37+
/// ```
38+
///
39+
/// = Known behaviours
40+
///
41+
// - `#till-next` should be put at the same level of `#show: mark-till-next`, or it will be ignored.
42+
// - If you put two `#till-next` consecutively, then the former `#till-next` will receive a space `[ ]`, not `none`.
43+
#let till-next(fn) = metadata((till-next: fn))
44+
45+
/// A show rule that makes `#till-next(fn)` effective.
46+
///
47+
/// Usage: `#show: mark-till-next`
48+
#let mark-till-next(body) = {
49+
// The wrapper function
50+
let fn = none
51+
// The fenced elements to be wrapped
52+
let fenced = ()
53+
54+
for it in body.children {
55+
let is-the-metadata = it.func() == metadata and it.value.keys().contains("till-next")
56+
let is-heading = it.func() == heading
57+
58+
if is-the-metadata or is-heading {
59+
if fn != none {
60+
// Complete the last fence
61+
fn(fenced.join())
62+
fn = none
63+
fenced = ()
64+
}
65+
if is-the-metadata {
66+
// Start a new fence
67+
fn = it.value.till-next
68+
} else {
69+
it
70+
}
71+
} else if fn != none {
72+
// Continue the fence
73+
fenced.push(it)
74+
} else {
75+
it // if not in any fence
76+
}
77+
}
78+
79+
// Complete the last fence
80+
if fn != none {
81+
fn(fenced.join())
82+
}
83+
}

0 commit comments

Comments
 (0)