Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions scripts/rename-vendor-alphatex.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env bash
set -euo pipefail

# Rename vendor-alphatex-* files in en/ and zh-cn/ by removing the prefix
# Usage: ./scripts/rename-vendor-alphatex.sh (dry-run)
# ./scripts/rename-vendor-alphatex.sh --apply (perform changes)

ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
DIRS=("$ROOT_DIR/src/renderer/data/tutorials/en" "$ROOT_DIR/src/renderer/data/tutorials/zh-cn")
APPLY=false

if [[ "${1:-}" == "--apply" ]]; then
APPLY=true
fi

echo "Scanning for files to rename (prefix: vendor-alphatex-)..."
renames=()
for d in "${DIRS[@]}"; do
if [[ -d "$d" ]]; then
while IFS= read -r -d $'\0' f; do
base=$(basename "$f")
newbase=${base#vendor-alphatex-}
renames+=("$f::$d/$newbase")
done < <(find "$d" -maxdepth 1 -type f -name 'vendor-alphatex-*.mdx' -print0)
fi
done

if [[ ${#renames[@]} -eq 0 ]]; then
echo "No files found to rename. Nothing to do." >&2
exit 0
fi

echo "Planned renames:"
for r in "${renames[@]}"; do
IFS='::' read -r src dst <<< "$r"
echo " $src -> $dst"
done

# detect places where the prefix appears in repo files
echo
echo "Searching for references to 'vendor-alphatex-' in src files..."
refs=$(git grep -n --full-name -I "vendor-alphatex-" -- src || true)
if [[ -n "$refs" ]]; then
echo "Found references in the following files:"
echo "$refs"
else
echo "No references found in tracked src files. (There may still be matches in JSON or docs.)"
fi

if [[ "$APPLY" != true ]]; then
echo
echo "Dry run complete. To apply changes, run:"
echo " $0 --apply"
exit 0
fi

# Confirm before applying
read -rp "Apply the changes above? [y/N] " confirm
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
echo "Aborted by user." >&2
exit 1
fi

# Perform renames (use git mv if inside a git repo)
inside_git=false
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
inside_git=true
fi

for r in "${renames[@]}"; do
IFS='::' read -r src dst <<< "$r"
dst_dir=$(dirname "$dst")
mkdir -p "$dst_dir"
if [[ "$inside_git" == true ]]; then
git mv "$src" "$dst"
else
mv "$src" "$dst"
fi
echo "Renamed: $src -> $dst"
done

# Replace id references in tutorials registry and index.ts and any source files
# We replace occurrences of vendor-alphatex-<slug> -> <slug>
# Use perl for cross-platform in-place edits

echo "Updating references in files..."
# files to update explicitly
perl -0777 -pe 's/"vendor-alphatex-([A-Za-z0-9_\-]+)"/"$1"/g' -i "$ROOT_DIR/src/renderer/data/tutorials/vendor-alphatex-registry.json"
perl -0777 -pe 's/id:\s*"vendor-alphatex-([A-Za-z0-9_\-]+)"/id: "$1"/g' -i "$ROOT_DIR/src/renderer/data/tutorials/index.ts"

# Update any other source files under src/ referencing vendor-alphatex-
# Only touch string-like occurrences to be conservative
while IFS= read -r -d $'\0' file; do
echo "Patching: $file"
perl -0777 -pe 's/vendor-alphatex-([A-Za-z0-9_\-]+)/$1/g' -i "$file"
done < <(git grep -lz --full-name -I "vendor-alphatex-" -- src || true)

# Stage changes if in git
if [[ "$inside_git" == true ]]; then
git add -A
echo "Changes staged. Please review and commit (or amend as needed)."
else
echo "Changes applied (no git detected). Please review and commit the changes manually."
fi

echo "Done. Recommendation: run 'pnpm format' and 'pnpm check' to ensure code style and type checks."
98 changes: 51 additions & 47 deletions src/renderer/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,55 +186,59 @@ export function Sidebar({ onCollapse }: SidebarProps) {
</Tooltip>
)}

<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 hover:bg-blue-500/20 hover:text-blue-600"
onClick={handleOpenFile}
>
<FolderOpen className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>打开文件</p>
</TooltipContent>
</Tooltip>
{workspaceMode !== "tutorial" && (
<>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 hover:bg-blue-500/20 hover:text-blue-600"
onClick={handleOpenFile}
>
<FolderOpen className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>打开文件</p>
</TooltipContent>
</Tooltip>

<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 hover:bg-blue-500/20 hover:text-blue-600"
onClick={() => handleNewFileWithExt(".atex")}
>
<span className="sr-only">新建 .atex 文件</span>
<FileMusic className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>新建 .atex</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 hover:bg-blue-500/20 hover:text-blue-600"
onClick={() => handleNewFileWithExt(".atex")}
>
<span className="sr-only">新建 .atex 文件</span>
<FileMusic className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>新建 .atex</p>
</TooltipContent>
</Tooltip>

<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 hover:bg-blue-500/20 hover:text-blue-600"
onClick={() => handleNewFileWithExt(".md")}
>
<span className="sr-only">新建 .md 文件</span>
<FileDown className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>新建 .md</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 hover:bg-blue-500/20 hover:text-blue-600"
onClick={() => handleNewFileWithExt(".md")}
>
<span className="sr-only">新建 .md 文件</span>
<FileDown className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>新建 .md</p>
</TooltipContent>
</Tooltip>
</>
)}

<Tooltip>
<TooltipTrigger asChild>
Expand Down
49 changes: 27 additions & 22 deletions src/renderer/components/TutorialView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,32 +104,37 @@ export default function TutorialView() {
/>

<div className="flex-1 p-4 overflow-auto">
{loading && (
<div className="flex items-center justify-center h-full">
<p className="text-sm text-muted-foreground">加载中...</p>
</div>
)}
{/* Content container: center with a generous max width to avoid right overflow */}
<div className="mx-auto w-full max-w-[900px]">
{loading && (
<div className="flex items-center justify-center h-full">
<p className="text-sm text-muted-foreground">加载中...</p>
</div>
)}

{error && (
<div className="bg-destructive/10 border border-destructive rounded p-4">
<p className="text-sm text-destructive">{error}</p>
</div>
)}
{error && (
<div className="bg-destructive/10 border border-destructive rounded p-4">
<p className="text-sm text-destructive">{error}</p>
</div>
)}

{/* 如果加载了 MDX 模块,使用 MDX 渲染器 */}
{!loading && !error && mdxModule && <MDXRenderer module={mdxModule} />}
{/* 如果加载了 MDX 模块,使用 MDX 渲染器 */}
{!loading && !error && mdxModule && (
<MDXRenderer module={mdxModule} />
)}

{/* 否则使用 Markdown 渲染器 */}
{!loading && !error && !mdxModule && content && (
<TutorialRenderer content={content} />
)}
{/* 否则使用 Markdown 渲染器 */}
{!loading && !error && !mdxModule && content && (
<TutorialRenderer content={content} />
)}

{!loading && !error && !mdxModule && !content && metadata && (
<div>
<h2 className="text-lg font-semibold mb-2">{metadata.title}</h2>
<p className="text-sm text-muted-foreground">教程内容为空</p>
</div>
)}
{!loading && !error && !mdxModule && !content && metadata && (
<div>
<h2 className="text-lg font-semibold mb-2">{metadata.title}</h2>
<p className="text-sm text-muted-foreground">教程内容为空</p>
</div>
)}
</div>
</div>
</div>
);
Expand Down
17 changes: 15 additions & 2 deletions src/renderer/components/tutorial/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export function CodeBlock({ language, children, className }: CodeBlockProps) {
const detectedLanguage =
language || className?.replace(/language-/, "") || "text";

// 将 alphatex 映射到 markdown 作为回退(当前没有专用高亮器)
let finalLanguage = detectedLanguage
? String(detectedLanguage).toLowerCase()
: "text";
if (finalLanguage === "alphatex") finalLanguage = "markdown";

// 清理代码内容:移除首尾的换行符(语义字符不应由这里处理)
const code = String(children || "").replace(/^\n+|\n+$/g, "");

Expand All @@ -60,10 +66,17 @@ export function CodeBlock({ language, children, className }: CodeBlockProps) {
const cleanedTheme = removeBackgroundFromTheme(theme);

return (
<div className="not-prose my-4 overflow-hidden rounded-md border border-border bg-muted/30 code-block-no-text-bg">
<div className="not-prose my-4 overflow-x-auto rounded-md border border-border bg-muted/30 code-block-no-text-bg">
<SyntaxHighlighter
language={detectedLanguage}
language={finalLanguage}
style={cleanedTheme}
wrapLongLines={true}
lineProps={{
style: {
whiteSpace: finalLanguage === "markdown" ? "pre-wrap" : "pre",
wordBreak: "break-word",
},
}}
customStyle={{
margin: 0,
padding: "0.5rem 0.75rem",
Expand Down
18 changes: 14 additions & 4 deletions src/renderer/components/tutorial/MDXRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ const allComponents = {
<h4 className="text-base font-medium mt-3 mb-2">{children}</h4>
),
p: ({ children }: { children?: React.ReactNode }) => (
<p className="text-sm text-foreground mb-4 leading-relaxed">{children}</p>
<p className="text-sm text-foreground mb-4 leading-relaxed break-words whitespace-normal">
{children}
</p>
),
ul: ({ children }: { children?: React.ReactNode }) => (
<ul className="list-disc list-inside mb-4 space-y-2 text-sm">{children}</ul>
Expand All @@ -44,7 +46,7 @@ const allComponents = {
a: ({ href, children }: { href?: string; children?: React.ReactNode }) => (
<a
href={href}
className="text-primary hover:underline"
className="text-primary hover:underline break-words whitespace-normal"
target={href?.startsWith("http") ? "_blank" : undefined}
rel={href?.startsWith("http") ? "noopener noreferrer" : undefined}
>
Expand All @@ -66,10 +68,18 @@ const allComponents = {
children?: React.ReactNode;
className?: string;
}) => {
// 内联代码
// 如果没有 className,区分内联 vs 块级:包含换行视为块级代码
const text = String(children || "");
if (!className) {
if (text.includes("\n")) {
return (
<mdxComponents.CodeBlock>
{String(children || "").replace(/\n$/, "")}
</mdxComponents.CodeBlock>
);
}
return (
<code className="px-1.5 py-0.5 bg-muted rounded text-sm font-mono before:content-none after:content-none">
<code className="px-1.5 py-0.5 bg-muted rounded text-sm font-mono before:content-none after:content-none break-words whitespace-normal">
{children}
</code>
);
Expand Down
Loading