diff --git a/app/components/CharCells.vue b/app/components/CharCells.vue index fec26ca..d0f791b 100644 --- a/app/components/CharCells.vue +++ b/app/components/CharCells.vue @@ -19,7 +19,7 @@ const { t } = useT() const { regions, regionIndices, tracks, showOld } = useColumnVisibility() // Read over the columns on show: with Japan hidden, a row that ran -// CN | HK+TW | JP has two runs, not three with a gap where Japan was. +// CN | JP | HK+TW has two runs, not three with a gap where Japan was. const signature = computed(() => projectSignature( props.dimension === 'glyph' ? props.row.glyph : props.row.cp, diff --git a/app/components/OverprintChar.vue b/app/components/OverprintChar.vue index cbe5a38..6ae8b9d 100644 --- a/app/components/OverprintChar.vue +++ b/app/components/OverprintChar.vue @@ -3,9 +3,9 @@ import { fontRegionOf, glyphSignature, projectSignature, + signatureIndexOf, } from '~~/shared/row.ts' import { - COLUMNS, REGIONS, type CharRow, type Column, @@ -57,7 +57,7 @@ const basis = computed(() => const groups = computed(() => projectSignature( glyphSignature(props.row), - basis.value.map((column) => COLUMNS.indexOf(column)), + basis.value.map(signatureIndexOf), ), ) diff --git a/app/composables/chars.ts b/app/composables/chars.ts index 0b3db67..cce4ec7 100644 --- a/app/composables/chars.ts +++ b/app/composables/chars.ts @@ -86,7 +86,7 @@ const charIndex = ((): Map => { /** * A row's partition signature under the chosen comparison dimension, read over * the columns on show. Hiding a column repartitions what is left, so a row - * whose shown regions ran CN | HK+TW | JP becomes a two-form row once Japan is + * whose shown regions ran CN | JP | HK+TW becomes a two-form row once Japan is * out -- and lands under the chip that says so. */ export const signatureOf = ( diff --git a/app/composables/prefs.ts b/app/composables/prefs.ts index 9d5218f..f9f9d8f 100644 --- a/app/composables/prefs.ts +++ b/app/composables/prefs.ts @@ -66,12 +66,14 @@ export function useColumnVisibility() { : chosen }) - /** Columns on show, in CN-HK-TW-JP-KR-old order. */ + /** Columns on show, in CN-JP-old-HK-TW-KR display order. */ const columns = computed(() => COLUMNS.filter((column) => !off.value.has(column)), ) const regions = computed(() => - REGIONS.filter((region) => !off.value.has(region)), + COLUMNS.filter( + (column): column is Region => column !== 'old' && !off.value.has(column), + ), ) /** The same regions as indices into REGIONS, which is how tuples are read. */ const regionIndices = computed(() => diff --git a/app/locales/ja-jp.ts b/app/locales/ja-jp.ts index 348e2e2..e95953d 100644 --- a/app/locales/ja-jp.ts +++ b/app/locales/ja-jp.ts @@ -32,7 +32,7 @@ export const jaJP: typeof zhCN = { title: '表示設定', language: '表示言語', emoji: '地域を旗で表示', - emojiHint: '「中・港・台・日・韓」を対応する旗の記号に置き換えます。', + emojiHint: '「中・日・港・台・韓」を対応する旗の記号に置き換えます。', outline: '重ね表示で輪郭線を使う', outlineHint: '重ねた字形を輪郭線で表示します。画が一つに潰れにくくなり、違いが分かりやすくなります。', diff --git a/app/locales/ko-kr.ts b/app/locales/ko-kr.ts index 244cb59..1fd1e7e 100644 --- a/app/locales/ko-kr.ts +++ b/app/locales/ko-kr.ts @@ -32,7 +32,7 @@ export const koKR: typeof zhCN = { title: '표시 설정', language: '인터페이스 언어', emoji: '지역을 국기로 표시', - emojiHint: '‘중·홍·대·일·한’ 표기를 해당 국기 기호로 바꿉니다.', + emojiHint: '‘중·일·홍·대·한’ 표기를 해당 국기 기호로 바꿉니다.', outline: '겹쳐 보기에서 윤곽선 사용', outlineHint: '겹친 자형을 윤곽선으로 표시해 획이 한 덩어리로 뭉치지 않고 차이가 더 잘 보이게 합니다.', diff --git a/app/locales/zh-cn.ts b/app/locales/zh-cn.ts index c866574..69b0b18 100644 --- a/app/locales/zh-cn.ts +++ b/app/locales/zh-cn.ts @@ -30,7 +30,7 @@ export const zhCN = { title: '显示选项', language: '界面语言', emoji: '用旗帜显示地区', - emojiHint: '把「中港台日韩」换成对应的旗帜符号。', + emojiHint: '把「中日港台韩」换成对应的旗帜符号。', outline: '叠印用空心字', outlineHint: '把叠在一起的字形改成描边,笔画不再糊成一团,分歧处更清楚。', columns: '参与对照的字形', diff --git a/app/locales/zh-hk.ts b/app/locales/zh-hk.ts index 5d0fa5e..199e954 100644 --- a/app/locales/zh-hk.ts +++ b/app/locales/zh-hk.ts @@ -32,7 +32,7 @@ export const zhHK: typeof zhCN = { title: '顯示選項', language: '介面語言', emoji: '用旗幟顯示地區', - emojiHint: '把「中港台日韓」換成對應的旗幟符號。', + emojiHint: '把「中日港台韓」換成對應的旗幟符號。', outline: '疊印用空心字', outlineHint: '把疊在一起的字形改成描邊,筆畫不再糊成一團,分歧處更清楚。', columns: '參與對照的字形', diff --git a/app/locales/zh-tw.ts b/app/locales/zh-tw.ts index 91a5284..f94b4be 100644 --- a/app/locales/zh-tw.ts +++ b/app/locales/zh-tw.ts @@ -32,7 +32,7 @@ export const zhTW: typeof zhCN = { title: '顯示選項', language: '介面語言', emoji: '用旗幟顯示地區', - emojiHint: '把「中港臺日韓」換成對應的旗幟符號。', + emojiHint: '把「中日港臺韓」換成對應的旗幟符號。', outline: '疊印用空心字', outlineHint: '把疊在一起的字形改成描邊,筆畫不再糊成一團,分歧處更清楚。', columns: '參與對照的字形', diff --git a/app/pages/char/[key].vue b/app/pages/char/[key].vue index 347c2d7..036da48 100644 --- a/app/pages/char/[key].vue +++ b/app/pages/char/[key].vue @@ -4,8 +4,9 @@ import { fontRegionOf, glyphSignature, projectSignature, + signatureIndexOf, } from '~~/shared/row.ts' -import { COLUMNS, REGIONS, type Column } from '~~/shared/types.ts' +import { REGIONS, type Column } from '~~/shared/types.ts' import { charPath, morphName, @@ -100,7 +101,7 @@ const backTo = computed(() => listPlace.value?.fullPath ?? '/') const groups = computed(() => projectSignature( glyphSignature(row.value!), - columns.value.map((column) => COLUMNS.indexOf(column)), + columns.value.map(signatureIndexOf), ), ) diff --git a/scripts/tests/columns.test.ts b/scripts/tests/columns.test.ts index 1a3d28c..803d7b8 100644 --- a/scripts/tests/columns.test.ts +++ b/scripts/tests/columns.test.ts @@ -6,6 +6,7 @@ import { listingOptionsFor } from '../../shared/listings.ts' import { glyphSignature, projectSignature, + signatureIndexOf, varietyOf, } from '../../shared/row.ts' import { @@ -38,6 +39,19 @@ const without = (...hidden: Region[]) => const ALL_COLUMNS = [...REGIONS].map((region) => REGIONS.indexOf(region)) const DEFAULT_COLUMNS = without('kr') +describe('column ordering', () => { + it('shows mainland, Japan, old Japan, Hong Kong, Taiwan, then Korea', () => { + expect(COLUMNS).toEqual(['cn', 'jp', 'old', 'hk', 'tw', 'kr']) + expect(COLUMNS.map(signatureIndexOf)).toEqual([0, 3, 5, 1, 2, 4]) + expect( + projectSignature( + glyphSignature(row('國')), + COLUMNS.map(signatureIndexOf), + ), + ).toBe('001111') + }) +}) + describe('reading a partition over the columns on show', () => { it('leaves a full row exactly as the data ships it', () => { for (const key of ['返', '骨', '海', '的']) @@ -71,8 +85,7 @@ describe('reading a partition over the columns on show', () => { // 國: the mainland and Japan write 国, Hong Kong and Taiwan write 國 -- // and so does the Japanese old form. expect(glyphSignature(row('國'))).toBe('011011') - const columns = (...keep: Column[]) => - keep.map((column) => COLUMNS.indexOf(column)) + const columns = (...keep: Column[]) => keep.map(signatureIndexOf) expect( projectSignature(glyphSignature(row('國')), columns('hk', 'tw', 'old')), ).toBe('000') diff --git a/shared/listings.ts b/shared/listings.ts index 1c60c6e..c0f2cad 100644 --- a/shared/listings.ts +++ b/shared/listings.ts @@ -14,13 +14,13 @@ export const LISTING_OPTIONS: readonly ListingOption[] = [ { id: 'cn1', kind: 'tier', region: 'cn', tier: 1 }, { id: 'cn2', kind: 'tier', region: 'cn', tier: 2 }, { id: 'cn3', kind: 'tier', region: 'cn', tier: 3 }, + { id: 'jp1', kind: 'tier', region: 'jp', tier: 1 }, + { id: 'jp2', kind: 'tier', region: 'jp', tier: 2 }, + { id: 'old', kind: 'old', region: 'jp' }, { id: 'hk1', kind: 'tier', region: 'hk', tier: 1 }, { id: 'tw1', kind: 'tier', region: 'tw', tier: 1 }, { id: 'tw2', kind: 'tier', region: 'tw', tier: 2 }, - { id: 'jp1', kind: 'tier', region: 'jp', tier: 1 }, - { id: 'jp2', kind: 'tier', region: 'jp', tier: 2 }, { id: 'kr1', kind: 'tier', region: 'kr', tier: 1 }, - { id: 'old', kind: 'old', region: 'jp' }, ] /** diff --git a/shared/row.ts b/shared/row.ts index ec3763e..fe9dea4 100644 --- a/shared/row.ts +++ b/shared/row.ts @@ -1,4 +1,4 @@ -import { REGIONS, type CharRow, type Region } from './types.ts' +import { REGIONS, type CharRow, type Column, type Region } from './types.ts' /** * Which region's font should render this cell: the earliest region in its @@ -66,6 +66,11 @@ export function glyphSignature(row: CharRow): string { return row.old ? row.glyph + row.old.glyph : row.glyph } +/** Position of a displayed column in glyphSignature's stored-region order. */ +export function signatureIndexOf(column: Column): number { + return column === 'old' ? REGIONS.length : REGIONS.indexOf(column) +} + /** * A signature restricted to the columns on show, renumbered so groups are * named by first appearance among them. diff --git a/shared/types.ts b/shared/types.ts index 5fc366f..10a465a 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -1,5 +1,5 @@ -/** The five regions, fixed in CN-HK-TW-JP-KR order: column position carries - * regional identity, color carries only grouping. */ +/** The five regions in stored tuple order. Column position carries regional + * identity in generated data; display order is defined separately below. */ export const REGIONS = ['cn', 'hk', 'tw', 'jp', 'kr'] as const export type Region = (typeof REGIONS)[number] @@ -11,10 +11,10 @@ export const STYLES = ['sans', 'serif'] as const export type Style = (typeof STYLES)[number] /** - * What the detail page compares: the five regions, plus Japan's pre-reform - * form where a row has one. The list pages compare regions alone. + * Display order for the five regions and Japan's pre-reform form. Keeping this + * separate from REGIONS lets generated tuples retain their stable data shape. */ -export const COLUMNS = [...REGIONS, 'old'] as const +export const COLUMNS = ['cn', 'jp', 'old', 'hk', 'tw', 'kr'] as const export type Column = (typeof COLUMNS)[number] /** Korea is available as an opt-in comparison; all other columns start on. */