Compare commits
No commits in common. "028074e4f1c3762e18a9ffba0c0f5c4ca625898d" and "c5e091da084f132f13743f6a659a0aa5169597f6" have entirely different histories.
028074e4f1
...
c5e091da08
|
|
@ -29,24 +29,22 @@ const SidebarContent: Component<SidebarContentProps> = (props) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex flex-col h-full">
|
<div class="p-4">
|
||||||
<div class="p-4 border-b">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<div class="flex items-center justify-between">
|
<h2 class="text-lg font-bold text-gray-900">目录</h2>
|
||||||
<h2 class="text-lg font-bold text-gray-900">目录</h2>
|
<Show when={!props.isDesktop}>
|
||||||
<Show when={!props.isDesktop}>
|
<button
|
||||||
<button
|
onClick={props.onClose}
|
||||||
onClick={props.onClose}
|
class="text-gray-500 hover:text-gray-700"
|
||||||
class="text-gray-500 hover:text-gray-700"
|
title="关闭"
|
||||||
title="关闭"
|
>
|
||||||
>
|
✕
|
||||||
✕
|
</button>
|
||||||
</button>
|
</Show>
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 文件树滚动区域 */}
|
{/* 文件树 */}
|
||||||
<div class="flex-1 overflow-y-auto p-4 min-h-0">
|
<div class="mb-4">
|
||||||
<h3 class="text-xs font-semibold text-gray-500 uppercase mb-2 px-2">
|
<h3 class="text-xs font-semibold text-gray-500 uppercase mb-2 px-2">
|
||||||
文件
|
文件
|
||||||
</h3>
|
</h3>
|
||||||
|
|
@ -61,9 +59,9 @@ const SidebarContent: Component<SidebarContentProps> = (props) => {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 当前文件标题滚动区域 */}
|
{/* 当前文件标题 */}
|
||||||
<Show when={currentFileHeadings().length > 0}>
|
<Show when={currentFileHeadings().length > 0}>
|
||||||
<div class="flex-1 border-t overflow-y-auto p-4 min-h-0">
|
<div class="xl:fixed xl:top-20 xl:right-4 xl:bottom-4 xl:overflow-y-auto xl:max-w-30 2xl:max-w-60">
|
||||||
<h3 class="text-xs font-semibold text-gray-500 uppercase mb-2 px-2">
|
<h3 class="text-xs font-semibold text-gray-500 uppercase mb-2 px-2">
|
||||||
本页
|
本页
|
||||||
</h3>
|
</h3>
|
||||||
|
|
@ -106,7 +104,7 @@ export const MobileSidebar: Component<SidebarProps> = (props) => {
|
||||||
/>
|
/>
|
||||||
{/* 侧边栏 */}
|
{/* 侧边栏 */}
|
||||||
<aside
|
<aside
|
||||||
class={`fixed top-0 left-0 h-full w-64 bg-white shadow-lg z-50 transform transition-transform duration-300 ease-in-out md:hidden ${
|
class={`fixed top-0 left-0 h-full w-64 bg-white shadow-lg z-50 overflow-y-auto transform transition-transform duration-300 ease-in-out md:hidden ${
|
||||||
props.isOpen ? "translate-x-0" : "-translate-x-full"
|
props.isOpen ? "translate-x-0" : "-translate-x-full"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|
@ -137,7 +135,7 @@ export const DesktopSidebar: Component<{}> = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside class="hidden md:block fixed top-0 left-0 h-full w-64 bg-white shadow-lg z-30 overflow-hidden pt-16">
|
<aside class="hidden md:block fixed top-0 left-0 h-full w-64 bg-white shadow-lg z-30 overflow-y-auto pt-16">
|
||||||
<SidebarContent
|
<SidebarContent
|
||||||
fileTree={fileTree()}
|
fileTree={fileTree()}
|
||||||
pathHeadings={pathHeadings()}
|
pathHeadings={pathHeadings()}
|
||||||
|
|
|
||||||
|
|
@ -1,334 +0,0 @@
|
||||||
import { createStore } from "solid-js/store";
|
|
||||||
import type {
|
|
||||||
CharacterStats,
|
|
||||||
CharacterSaves,
|
|
||||||
InventoryItem,
|
|
||||||
MothershipCharacter,
|
|
||||||
MothershipStoreState,
|
|
||||||
VitalValue,
|
|
||||||
StressValue,
|
|
||||||
} from "./types";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建默认角色数据
|
|
||||||
*/
|
|
||||||
export function createDefaultCharacter(): MothershipCharacter {
|
|
||||||
return {
|
|
||||||
stats: {
|
|
||||||
strength: 50,
|
|
||||||
agility: 50,
|
|
||||||
combat: 50,
|
|
||||||
intellect: 50,
|
|
||||||
},
|
|
||||||
saves: {
|
|
||||||
fear: 50,
|
|
||||||
sanity: 50,
|
|
||||||
body: 50,
|
|
||||||
},
|
|
||||||
skills: [],
|
|
||||||
inventory: [],
|
|
||||||
status: [],
|
|
||||||
hp: { current: 0, max: 0 },
|
|
||||||
stress: { current: 0, min: 0 },
|
|
||||||
wounds: { current: 0, max: 0 },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 限制数值在 0-99 范围内
|
|
||||||
*/
|
|
||||||
function clampStat(value: number): number {
|
|
||||||
return Math.max(0, Math.min(99, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 限制数值在指定范围内
|
|
||||||
*/
|
|
||||||
function clampValue(value: number, min: number, max: number): number {
|
|
||||||
return Math.max(min, Math.min(max, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
const [store, setStore] = createStore<MothershipStoreState>({
|
|
||||||
character: createDefaultCharacter(),
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新单个统计值
|
|
||||||
*/
|
|
||||||
export function setStat<K extends keyof CharacterStats>(
|
|
||||||
key: K,
|
|
||||||
value: number
|
|
||||||
): void {
|
|
||||||
setStore("character", "stats", key, clampStat(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量更新统计值
|
|
||||||
*/
|
|
||||||
export function setStats(stats: Partial<CharacterStats>): void {
|
|
||||||
setStore("character", "stats", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
...Object.fromEntries(
|
|
||||||
Object.entries(stats).map(([key, value]) => [key, clampStat(value)])
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新单个豁免值
|
|
||||||
*/
|
|
||||||
export function setSave<K extends keyof CharacterSaves>(
|
|
||||||
key: K,
|
|
||||||
value: number
|
|
||||||
): void {
|
|
||||||
setStore("character", "saves", key, clampStat(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量更新豁免值
|
|
||||||
*/
|
|
||||||
export function setSaves(saves: Partial<CharacterSaves>): void {
|
|
||||||
setStore("character", "saves", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
...Object.fromEntries(
|
|
||||||
Object.entries(saves).map(([key, value]) => [key, clampStat(value)])
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加技能
|
|
||||||
*/
|
|
||||||
export function addSkill(skill: string): void {
|
|
||||||
setStore("character", "skills", (prev) => [...prev, skill]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除技能
|
|
||||||
*/
|
|
||||||
export function removeSkill(skill: string): void {
|
|
||||||
setStore("character", "skills", (prev) =>
|
|
||||||
prev.filter((s) => s !== skill)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置技能列表
|
|
||||||
*/
|
|
||||||
export function setSkills(skills: string[]): void {
|
|
||||||
setStore("character", "skills", [...skills]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加物品到物品栏
|
|
||||||
*/
|
|
||||||
export function addInventoryItem(
|
|
||||||
name: string,
|
|
||||||
quantity: number = 1,
|
|
||||||
attributes?: Record<string, any>
|
|
||||||
): void {
|
|
||||||
setStore("character", "inventory", (prev) => [
|
|
||||||
...prev,
|
|
||||||
{ name, quantity: Math.max(1, quantity), attributes },
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从物品栏移除物品(通过名称)
|
|
||||||
*/
|
|
||||||
export function removeInventoryItem(name: string): void {
|
|
||||||
setStore("character", "inventory", (prev) =>
|
|
||||||
prev.filter((item) => item.name !== name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新物品数量
|
|
||||||
*/
|
|
||||||
export function updateInventoryItemQuantity(
|
|
||||||
name: string,
|
|
||||||
quantity: number
|
|
||||||
): void {
|
|
||||||
setStore("character", "inventory", (prev) =>
|
|
||||||
prev.map((item) =>
|
|
||||||
item.name === name
|
|
||||||
? { ...item, quantity: Math.max(0, quantity) }
|
|
||||||
: item
|
|
||||||
).filter((item) => item.quantity > 0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新物品属性
|
|
||||||
*/
|
|
||||||
export function updateInventoryItemAttributes(
|
|
||||||
name: string,
|
|
||||||
attributes: Record<string, any>
|
|
||||||
): void {
|
|
||||||
setStore("character", "inventory", (prev) =>
|
|
||||||
prev.map((item) =>
|
|
||||||
item.name === name
|
|
||||||
? { ...item, attributes }
|
|
||||||
: item
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加状态效果
|
|
||||||
*/
|
|
||||||
export function addStatus(
|
|
||||||
name: string,
|
|
||||||
quantity: number = 1,
|
|
||||||
attributes?: Record<string, any>
|
|
||||||
): void {
|
|
||||||
setStore("character", "status", (prev) => [
|
|
||||||
...prev,
|
|
||||||
{ name, quantity: Math.max(1, quantity), attributes },
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除状态效果
|
|
||||||
*/
|
|
||||||
export function removeStatus(name: string): void {
|
|
||||||
setStore("character", "status", (prev) =>
|
|
||||||
prev.filter((item) => item.name !== name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置 HP
|
|
||||||
*/
|
|
||||||
export function setHP(value: Partial<VitalValue>): void {
|
|
||||||
setStore("character", "hp", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
...value,
|
|
||||||
current: value.current !== undefined
|
|
||||||
? clampValue(value.current, 0, value.max ?? prev.max)
|
|
||||||
: prev.current,
|
|
||||||
max: value.max !== undefined
|
|
||||||
? Math.max(0, value.max)
|
|
||||||
: prev.max,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 受到伤害
|
|
||||||
*/
|
|
||||||
export function takeDamage(amount: number): void {
|
|
||||||
setStore("character", "hp", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
current: Math.max(0, prev.current - amount),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 治疗 HP
|
|
||||||
*/
|
|
||||||
export function healHP(amount: number): void {
|
|
||||||
setStore("character", "hp", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
current: Math.min(prev.max, prev.current + amount),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置压力值
|
|
||||||
*/
|
|
||||||
export function setStress(value: Partial<StressValue>): void {
|
|
||||||
setStore("character", "stress", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
...value,
|
|
||||||
current: value.current !== undefined
|
|
||||||
? clampValue(value.current, value.min ?? prev.min, Number.MAX_SAFE_INTEGER)
|
|
||||||
: prev.current,
|
|
||||||
min: value.min !== undefined ? Math.max(0, value.min) : prev.min,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 增加压力
|
|
||||||
*/
|
|
||||||
export function addStress(amount: number): void {
|
|
||||||
setStore("character", "stress", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
current: prev.current + amount,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 减少压力
|
|
||||||
*/
|
|
||||||
export function reduceStress(amount: number): void {
|
|
||||||
setStore("character", "stress", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
current: Math.max(prev.min, prev.current - amount),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置伤口值
|
|
||||||
*/
|
|
||||||
export function setWounds(value: Partial<VitalValue>): void {
|
|
||||||
setStore("character", "wounds", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
...value,
|
|
||||||
current: value.current !== undefined
|
|
||||||
? clampValue(value.current, 0, value.max ?? prev.max)
|
|
||||||
: prev.current,
|
|
||||||
max: value.max !== undefined
|
|
||||||
? Math.max(0, value.max)
|
|
||||||
: prev.max,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 增加伤口
|
|
||||||
*/
|
|
||||||
export function addWound(amount: number = 1): void {
|
|
||||||
setStore("character", "wounds", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
current: Math.min(prev.max, prev.current + amount),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 治疗伤口
|
|
||||||
*/
|
|
||||||
export function healWound(amount: number = 1): void {
|
|
||||||
setStore("character", "wounds", (prev) => ({
|
|
||||||
...prev,
|
|
||||||
current: Math.max(0, prev.current - amount),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置角色到默认状态
|
|
||||||
*/
|
|
||||||
export function resetCharacter(): void {
|
|
||||||
setStore("character", createDefaultCharacter());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置完整角色数据
|
|
||||||
*/
|
|
||||||
export function setCharacter(character: MothershipCharacter): void {
|
|
||||||
setStore("character", character);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前角色数据
|
|
||||||
*/
|
|
||||||
export function getCharacter(): MothershipCharacter {
|
|
||||||
return store.character;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取 Store 订阅(用于 SolidJS 组件)
|
|
||||||
*/
|
|
||||||
export function useCharacterStore() {
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { store, setStore };
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
/**
|
|
||||||
* Mothership TRPG 角色表 Store
|
|
||||||
*
|
|
||||||
* @module journals/mothership
|
|
||||||
*/
|
|
||||||
|
|
||||||
export type {
|
|
||||||
CharacterStats,
|
|
||||||
CharacterSaves,
|
|
||||||
InventoryItem,
|
|
||||||
VitalValue,
|
|
||||||
StressValue,
|
|
||||||
MothershipCharacter,
|
|
||||||
MothershipStoreState,
|
|
||||||
} from "./types";
|
|
||||||
|
|
||||||
export {
|
|
||||||
// Store 核心
|
|
||||||
store,
|
|
||||||
setStore,
|
|
||||||
useCharacterStore,
|
|
||||||
getCharacter,
|
|
||||||
|
|
||||||
// 初始化
|
|
||||||
createDefaultCharacter,
|
|
||||||
resetCharacter,
|
|
||||||
setCharacter,
|
|
||||||
|
|
||||||
// Stats 操作
|
|
||||||
setStat,
|
|
||||||
setStats,
|
|
||||||
|
|
||||||
// Saves 操作
|
|
||||||
setSave,
|
|
||||||
setSaves,
|
|
||||||
|
|
||||||
// Skills 操作
|
|
||||||
addSkill,
|
|
||||||
removeSkill,
|
|
||||||
setSkills,
|
|
||||||
|
|
||||||
// Inventory 操作
|
|
||||||
addInventoryItem,
|
|
||||||
removeInventoryItem,
|
|
||||||
updateInventoryItemQuantity,
|
|
||||||
updateInventoryItemAttributes,
|
|
||||||
|
|
||||||
// Status 操作
|
|
||||||
addStatus,
|
|
||||||
removeStatus,
|
|
||||||
|
|
||||||
// HP 操作
|
|
||||||
setHP,
|
|
||||||
takeDamage,
|
|
||||||
healHP,
|
|
||||||
|
|
||||||
// Stress 操作
|
|
||||||
setStress,
|
|
||||||
addStress,
|
|
||||||
reduceStress,
|
|
||||||
|
|
||||||
// Wounds 操作
|
|
||||||
setWounds,
|
|
||||||
addWound,
|
|
||||||
healWound,
|
|
||||||
} from "./characterStore";
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
/**
|
|
||||||
* Mothership TRPG 角色表统计值
|
|
||||||
* 所有值范围为 0-99
|
|
||||||
*/
|
|
||||||
export interface CharacterStats {
|
|
||||||
/** 力量 */
|
|
||||||
strength: number;
|
|
||||||
/** 敏捷 */
|
|
||||||
agility: number;
|
|
||||||
/** 战斗 */
|
|
||||||
combat: number;
|
|
||||||
/** 智力 */
|
|
||||||
intellect: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mothership TRPG 角色表豁免值
|
|
||||||
* 所有值范围为 0-99
|
|
||||||
*/
|
|
||||||
export interface CharacterSaves {
|
|
||||||
/** 恐惧豁免 */
|
|
||||||
fear: number;
|
|
||||||
/** 理智豁免 */
|
|
||||||
sanity: number;
|
|
||||||
/** 体质豁免 */
|
|
||||||
body: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 物品栏物品
|
|
||||||
*/
|
|
||||||
export interface InventoryItem {
|
|
||||||
/** 物品名称 */
|
|
||||||
name: string;
|
|
||||||
/** 数量 */
|
|
||||||
quantity: number;
|
|
||||||
/** 自定义属性,如护甲值 { ap: 3 } */
|
|
||||||
attributes?: Record<string, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生命值/伤口等有最大值和当前值的属性
|
|
||||||
*/
|
|
||||||
export interface VitalValue {
|
|
||||||
current: number;
|
|
||||||
max: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 压力值(有最小值和当前值)
|
|
||||||
*/
|
|
||||||
export interface StressValue {
|
|
||||||
current: number;
|
|
||||||
min: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mothership 角色表完整数据结构
|
|
||||||
*/
|
|
||||||
export interface MothershipCharacter {
|
|
||||||
stats: CharacterStats;
|
|
||||||
saves: CharacterSaves;
|
|
||||||
skills: string[];
|
|
||||||
inventory: InventoryItem[];
|
|
||||||
status: InventoryItem[];
|
|
||||||
hp: VitalValue;
|
|
||||||
stress: StressValue;
|
|
||||||
wounds: VitalValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store 状态类型
|
|
||||||
*/
|
|
||||||
export type MothershipStoreState = {
|
|
||||||
character: MothershipCharacter;
|
|
||||||
};
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
import {TokenizerAndRendererExtension} from "marked";
|
|
||||||
|
|
||||||
export default function markedColumns(): TokenizerAndRendererExtension[] {
|
|
||||||
return [{
|
|
||||||
name: 'col-divider',
|
|
||||||
level: 'block',
|
|
||||||
start(src: string) {
|
|
||||||
return src.match(/^-\|-+ *\n/)?.index;
|
|
||||||
},
|
|
||||||
tokenizer(src){
|
|
||||||
const match = src.match(/^-\|(-+) *\n/);
|
|
||||||
if(!match) return;
|
|
||||||
return {
|
|
||||||
type: 'col-divider',
|
|
||||||
raw: match[0],
|
|
||||||
tokens: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
renderer(token){
|
|
||||||
const extra = token.raw.match(/^-\|(-+) *\n/)?.[1].length || 0;
|
|
||||||
const sfx = extra > 1 ? '-' + (extra) : '';
|
|
||||||
return `</div><div class="col${sfx}">`;
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
name: 'col-start',
|
|
||||||
level: 'block',
|
|
||||||
start(src: string) {
|
|
||||||
return src.match(/^\|--+ *\n/)?.index;
|
|
||||||
},
|
|
||||||
tokenizer(src){
|
|
||||||
const match = src.match(/^\|-(-+) *\n/);
|
|
||||||
if(!match) return;
|
|
||||||
return {
|
|
||||||
type: 'col-start',
|
|
||||||
raw: match[0],
|
|
||||||
tokens: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
renderer(token){
|
|
||||||
const extra = token.raw.match(/^\|-(-+) *\n/)?.[1].length || 0;
|
|
||||||
const sfx = extra > 1 ? '-' + (extra) : '';
|
|
||||||
return `<div class="cols"><div class="col${sfx}">`;
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
name: 'col-end',
|
|
||||||
level: 'block',
|
|
||||||
start(src: string) {
|
|
||||||
return src.match(/^--\| *\n/)?.index;
|
|
||||||
},
|
|
||||||
tokenizer(src){
|
|
||||||
const match = src.match(/^--\| *\n/);
|
|
||||||
if(!match) return;
|
|
||||||
return {
|
|
||||||
type: 'col-end',
|
|
||||||
raw: match[0],
|
|
||||||
tokens: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
renderer(token){
|
|
||||||
return `</div></div>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,6 @@ import markedAlert from "marked-alert";
|
||||||
import markedMermaid from "./mermaid";
|
import markedMermaid from "./mermaid";
|
||||||
import markedTable from "./table";
|
import markedTable from "./table";
|
||||||
import {gfmHeadingId} from "marked-gfm-heading-id";
|
import {gfmHeadingId} from "marked-gfm-heading-id";
|
||||||
import markedColumns from "./columns";
|
|
||||||
|
|
||||||
let globalIconPrefix: string | undefined = undefined;
|
let globalIconPrefix: string | undefined = undefined;
|
||||||
function overrideIconPrefix(path?: string){
|
function overrideIconPrefix(path?: string){
|
||||||
|
|
@ -46,10 +45,8 @@ const marked = new Marked()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]), {
|
]), {
|
||||||
extensions: [
|
|
||||||
...markedColumns(),
|
|
||||||
{
|
|
||||||
// 自定义代码块渲染器,支持 yaml/tag 格式
|
// 自定义代码块渲染器,支持 yaml/tag 格式
|
||||||
|
extensions: [{
|
||||||
name: 'code-block-yaml-tag',
|
name: 'code-block-yaml-tag',
|
||||||
level: 'block',
|
level: 'block',
|
||||||
start(src: string) {
|
start(src: string) {
|
||||||
|
|
|
||||||
|
|
@ -29,14 +29,14 @@ export default function markedTable(): MarkedExtension {
|
||||||
const header = token.header;
|
const header = token.header;
|
||||||
let roll = '';
|
let roll = '';
|
||||||
const labelIndex = header.findIndex(cell => {
|
const labelIndex = header.findIndex(cell => {
|
||||||
if(cell.text === 'md-roll-label' || cell.text.match(/(\d+)?d\d+/)){
|
if(cell.text === 'md-roll-label'){
|
||||||
roll = ' roll=true';
|
roll = ' roll=true';
|
||||||
return true;
|
return true;
|
||||||
}else if(cell.text === 'md-remix-label'){
|
}else if(cell.text === 'md-remix-label'){
|
||||||
roll = ' roll=true remix=true';
|
roll = ' roll=true remix=true';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return cell.text === 'md-table-label' || cell.text === 'label';
|
return cell.text === 'md-table-label';
|
||||||
});
|
});
|
||||||
|
|
||||||
// 默认表格渲染 - 使用 marked 默认行为
|
// 默认表格渲染 - 使用 marked 默认行为
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
import { getRoundedPolygonPoints, getTangentCircleCenter, getProjectedPoint } from './rounded';
|
import { getRoundedPolygonPoints, getTangentCircleCenter, getProjectedPoint } from './rounded';
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
declare const describe: any;
|
||||||
|
declare const test: any;
|
||||||
|
declare const expect: any;
|
||||||
|
|
||||||
describe('getProjectedPoint', () => {
|
describe('getProjectedPoint', () => {
|
||||||
test('should project point onto line segment', () => {
|
test('should project point onto line segment', () => {
|
||||||
// 点 (2, 2) 投影到线段 (0, 0) -> (4, 0)
|
// 点 (2, 2) 投影到线段 (0, 0) -> (4, 0)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||||
"types": ["node", "jest"]
|
"types": ["node"]
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"],
|
"include": ["src/**/*"],
|
||||||
"exclude": ["node_modules", "dist"]
|
"exclude": ["node_modules", "dist"]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue