<!DOCTYPE html><html lang="zh" data-theme="dark"><head><meta charset="utf-8"><meta name="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>当 True 并不是 True · Cytrogen 的个人博客</title><meta name="description" content="某天我阅读了 《Not Bad 的架构:解码虚空的中文源代码》,原本想要放入月刊内,结果发现自己写的越来越多,已经到了「不独立发个文章都对不起自己」的地步。"><link rel="icon" href="../favicon.png"><link rel="canonical" href="https://cytrogen.icu/posts/6e69.html"><link rel="webmention" href="https://webmention.io/cytrogen.icu/webmention"><link rel="me" href="https://m.otter.homes/@Cytrogen"><link rel="me" href="https://github.com/cytrogen"><meta name="fediverse:creator" content="@Cytrogen@m.otter.homes"><link rel="preload" href="../fonts/opensans-regular-latin.woff2" as="font" type="font/woff2" crossorigin="anonymous"><style>@font-face {
font-family: 'Open Sans';
src: url('../fonts/opensans-regular-latin.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
size-adjust: 107%;
ascent-override: 97%;
descent-override: 25%;
line-gap-override: 0%;
}
</style><script>(function() {
try {
// 优先级:用户选择 > 系统偏好 > 默认浅色
const saved = localStorage.getItem('theme');
const theme = saved ||
(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
} catch (error) {
// 失败时使用默认主题,不阻塞渲染
document.documentElement.setAttribute('data-theme', 'light');
}
})();
</script><link rel="stylesheet" href="../css/ares.css"><script data-netlify-skip-bundle="true">(function() {
document.addEventListener('DOMContentLoaded', function() {
const theme = document.documentElement.getAttribute('data-theme');
const pageWrapper = document.getElementById('page-wrapper');
if (pageWrapper && theme) {
pageWrapper.setAttribute('data-theme', theme);
}
});
})();
</script><!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hexo-math@4.0.0/dist/style.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 8.1.1"><link rel="alternate" href="atom.xml" title="Cytrogen 的个人博客" type="application/atom+xml">
</head><body><div id="page-wrapper"><a class="skip-link" href="#main-content">跳到主要内容</a><div class="wrap"><header><a class="logo-link" href="../index.html"><img src="../favicon.png" alt="logo"></a><div class="h-card visually-hidden"><img class="u-photo" src="https://cytrogen.icu/favicon.png" alt="Cytrogen"><a class="p-name u-url u-uid" href="https://cytrogen.icu">Cytrogen</a><p class="p-note">Cytrogen 的个人博客,Cytrogen's Blog</p><a class="u-url" rel="me noopener" target="_blank" href="https://m.otter.homes/@Cytrogen">Mastodon</a><a class="u-url" rel="me noopener" target="_blank" href="https://github.com/cytrogen">GitHub</a></div><nav class="site-nav"><div class="nav-main"><div class="nav-primary"><ul class="nav-list hidden-mobile"><li class="nav-item"><a class="nav-link" href="../index.html">首页</a></li></ul><div class="nav-tools"><div class="language-menu"><button class="language-toggle" type="button"><svg class="icon icon-globe" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855A7.97 7.97 0 0 0 5.145 4H7.5V1.077zM4.09 4a9.267 9.267 0 0 1 .64-1.539 6.7 6.7 0 0 1 .597-.933A7.025 7.025 0 0 0 2.255 4H4.09zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a6.958 6.958 0 0 0-.656 2.5h2.49zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5H4.847zM8.5 5v2.5h2.99a12.495 12.495 0 0 0-.337-2.5H8.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5H4.51zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5H8.5zM5.145 12c.138.386.295.744.468 1.068.552 1.035 1.218 1.65 1.887 1.855V12H5.145zm.182 2.472a6.696 6.696 0 0 1-.597-.933A9.268 9.268 0 0 1 4.09 12H2.255a7.024 7.024 0 0 0 3.072 2.472zM3.82 11a13.652 13.652 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5H3.82zm6.853 3.472A7.024 7.024 0 0 0 13.745 12H11.91a9.27 9.27 0 0 1-.64 1.539 6.688 6.688 0 0 1-.597.933zM8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855A7.97 7.97 0 0 0 10.855 12H8.5zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.65 13.65 0 0 1-.312 2.5zm2.802-3.5a6.959 6.959 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5h2.49zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7.024 7.024 0 0 0-3.072-2.472c.218.284.418.598.597.933zM10.855 4a7.966 7.966 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4h2.355z"></path></svg><span>中文</span></button><div class="language-dropdown"></div></div></div><div class="nav-controls"><div class="more-menu hidden-mobile"><button class="more-toggle" type="button"><span>更多</span><svg class="icon icon-chevron-down" width="12" height="12" viewBox="0 0 12 12" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1s.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0s.3.8 0 1.1l-3.3 3.3c-.1.1-.3.2-.5.2z"></path></svg></button><div class="more-dropdown"><ul class="dropdown-list"><li class="dropdown-item"><a class="nav-link" href="../archives/index.html">归档</a></li><li class="dropdown-item"><a class="nav-link" href="../categories/index.html">分类</a></li><li class="dropdown-item"><a class="nav-link" href="../tags/index.html">标签</a></li><li class="dropdown-item"><a class="nav-link" href="../about/index.html">关于</a></li><li class="dropdown-item"><a class="nav-link" href="../sitemap/index.html">领地地图</a></li></ul></div></div><div class="theme-switcher"><button class="theme-toggle" type="button" role="switch" aria-pressed="false" aria-label="切换主题"><div class="theme-icon moon-icon"><svg class="icon icon-moon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"></path></svg></div><div class="theme-icon sun-icon"><svg class="icon icon-sun" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"></path></svg></div></button></div><details class="mobile-menu-details hidden-desktop"><summary class="hamburger-menu" aria-label="nav.menu"><svg class="icon icon-bars" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"></path></svg><span class="menu-text">nav.menu</span></summary><div class="mobile-menu-dropdown"><ul class="mobile-nav-list"><li class="mobile-nav-item"><a class="mobile-nav-link" href="../index.html">首页</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../archives/index.html">归档</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../categories/index.html">分类</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../tags/index.html">标签</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../about/index.html">关于</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../sitemap/index.html">领地地图</a></li></ul></div></details></div></div></div></nav></header><main class="container" id="main-content" tabindex="-1"><div class="post"><article class="post-block h-entry"><div class="post-meta p-author h-card visually-hidden"><img class="author-avatar u-photo" src="../favicon.png" alt="Cytrogen"><span class="p-name">Cytrogen</span><a class="u-url" href="https://cytrogen.icu">https://cytrogen.icu</a></div><a class="post-permalink u-url u-uid visually-hidden" href="https://cytrogen.icu/posts/6e69.html">永久链接</a><div class="p-summary visually-hidden"><p>某天我阅读了 <a target="_blank" rel="noopener" href="https://suggger.substack.com/p/the-architecture-of-not-bad-decoding">《Not Bad 的架构:解码虚空的中文源代码》</a>,原本想要放入月刊内,结果发现自己写的越来越多,已经到了「不独立发个文章都对不起自己」的地步。</p></div><div class="visually-hidden"><a class="p-category" href="../categories/%E4%B8%AA%E4%BA%BA%E9%9A%8F%E6%83%B3/">个人随想</a><a class="p-category" href="../tags/%E8%AF%AD%E8%A8%80%E5%AD%A6/">语言学</a></div><h1 class="post-title p-name">当 True 并不是 True</h1><div class="post-info"><time class="post-date dt-published" datetime="2025-12-25T15:32:25.000Z">12/25/2025</time><time class="dt-updated visually-hidden" datetime="2026-02-09T17:16:55.213Z"></time></div><div class="post-content e-content"><html><head></head><body><p>某天我阅读了 <a target="_blank" rel="noopener" href="https://suggger.substack.com/p/the-architecture-of-not-bad-decoding">《Not Bad 的架构:解码虚空的中文源代码》</a>,原本想要放入月刊内,结果发现自己写的越来越多,已经到了「不独立发个文章都对不起自己」的地步。</p>
<span id="more"></span>
<h2 id="文章的大致内容"><a class="markdownIt-Anchor" href="#文章的大致内容"></a> 文章的大致内容</h2>
<p>在深入讨论之前,为了照顾没有阅读过作者 Suggger 原文的读者,我先快速梳理一下他的核心观点。</p>
<p>Suggger 的思考始于一个细微的翻译卡顿:他发现中文在表达「肯定」时,往往不喜欢直接说 <code>True</code>(是),而是更倾向于双重否定的 <code>!False</code>(非假)。</p>
<p>这是他举出的例子:</p>
<ul>
<li>没错 = Not wrong = Right</li>
<li>不差 = Not bad = Decent</li>
<li>还行 = Still passable = Okay</li>
<li>没事 = No problem = Fine</li>
</ul>
<p>Suggger 将这种现象总结为「无」的语言哲学。</p>
<p>他认为,相较于英文那种直接、明确、必须承担立场的 <u>分类思维</u>,中文的这种负向肯定构建了一种 <u>灰度思维</u>:它旨在避免直接承担责任,保留解释空间,并让态度始终保持模糊与可撤回性。</p>
<p>简而言之,他认为英语是在给世界打标签,而中文是在测算风险与留白。</p>
<h2 id="我的看法"><a class="markdownIt-Anchor" href="#我的看法"></a> 我的看法</h2>
<p>我看完这个文章后第一时间想到的是日语。</p>
<p>如果非要试图通过语言结构来窥探思维方式,我认为日语才是那个最极致的样本,因为他们的多重否认在这个世界上是相当独特的。</p>
<p>让我们先看几个例子。假设我们要表达「义务」的话,这三个语言是这么表达的:</p>
<ul>
<li>中文:必须</li>
<li>英文:Must / Have to</li>
<li>日语:しなければならない —— 直译就是「如果不做的话,不行」。</li>
</ul>
<p>很明显,日语用的是一个 <u>结构性的双重否定</u>,用来表达最强烈的「肯定」含义。</p>
<p>甚至在表达「只有」的时候:</p>
<ul>
<li>中文:我只有一个苹果</li>
<li>英文:I have only one apple</li>
<li>日语:りんごは<ruby>一<rt>ひと</rt></ruby>つしかない —— 除了一个苹果之外,<em>没有</em> 别的了</li>
</ul>
<p>在日常社交中,这种倾向更明显。比如邀请:</p>
<ul>
<li>中文:你想去吗?</li>
<li>英文:Do you want to go?</li>
<li>日语:<ruby>行<rt>い</rt></ruby>きませんか? —— 你 <em>不</em> 去吗?</li>
</ul>
<p>或者是拒绝:日本人想要拒绝时,他们几乎不会说「不」的,他们会说「それはちょっと……」或者简单点「ちょっと……」。直译是「那个有点……」。句尾甚至直接省略了否定词,只留下一个悬而未决的语气。</p>
<div class="danger alert-info"><p>当然,我这里话没有说那么死。这是因为虽然日语表达「必须」的核心语法结构确实是双重否定,但现代日语(尤其是口语)确实发生了变化,而且存在其他的表达方式。</p>
<p>哪怕是现在最懒、最年轻的日本人,在口语里表达「必须」时,通常会说:</p>
<ul>
<li>しなきゃ</li>
<li>しないと</li>
<li>しなくちゃ</li>
</ul>
<p>但是!即使是这些缩略语,它们的词源依然是双重否定,即「不这么做的话不行」:</p>
<ul>
<li>しなきゃ = しなければならない</li>
<li>しないと = しないといけない</li>
</ul>
<p>那么是否存在肯定形式呢?自然是有的,只是语感不太一样:</p>
<ul>
<li>するべき = 应该做(更多带有一种道德判断或强烈建议,而不是客观的「必须」)</li>
<li><ruby>必要<rt>ひつよう</rt></ruby>がある = 有做某事的必要(名词性的陈述)</li>
</ul>
</div>
<p>那么,我列举了这么多日语的例子,是为了证明「语言结构决定思维」吗?</p>
<p><u>弱萨丕尔・沃尔夫假说</u> 认为,语言结构强关联思维方式。这在学术上是有意义的,比如语言会影响我们对颜色的感知或对方位的描述。</p>
<p>但 Suggger 的错误在于,<strong>他将这种「影响」无限放大成了「决定」</strong>。他试图证明:因为你的语言里全是「否定」,所以你的骨子里就是「逃避」。如果这种理论成立,即语言结构决定逃避责任,那日本人应该是世界上最爱「推卸责任」的民族?这显然过于简化了。日本社会以极度严苛的责任感和耻感文化著称。这里的「否定结构」并不是为了逃避责任,而是一种社会性的<span class="emphasis">谦逊</span>。</p>
<p>日本文化中有一个核心概念叫<ruby>配虑<rt>はいりょ</rt></ruby>,即时时刻刻照顾对方的感受。直接的断言在日本社会往往被视为一种攻击或对他人的冒犯。因此,他们使用否定句式,不是为了像 Suggger 说的那样给自己留后路,而是为了降低自我的姿态,给对方留出面子和余地。</p>
<p>这就引出了那个鸡生蛋的问题:是语言的源代码决定了思维,还是文化的运行逻辑重塑了语言? 现实更可能是后者:<strong>文化的运行逻辑重塑了语言</strong>。日本的高语境、耻感文化需要一种不那么尖锐的语言工具来维持社会润滑,因此「多重否定」才演变成了一种语法规则。</p>
<p>理清了「文化重塑语言」,我们再来看中文,就会发现 Suggger 所谓的「中文否定肯定」和日语的「语法否定」本质完全不同。</p>
<p>日语的多重否定往往是语法层面的<span class="emphasis">刚需</span>。在表达「必须」、「只有」等基础概念时,日本人的选择并不多,语法结构几乎是强制他们调用「不…… 不行」或「不…… 没有」的模块。</p>
<p>但 <strong>中文的「否定肯定」是词汇层面的选择</strong>。当我们说「没错」或「还行」时,更多是出于一种松弛的口语习惯或社交修辞。我们完全拥有选择权,随时可以说「对的对的」、「正确的」、「确实」。我们的操作系统并没有禁止我们输出 <code>True</code>,只是我们在特定语境下选择了更温和的表达。</p>
<p>这里就必须提到 <u>语用学</u>。简单来说,语用学研究的是「在特定情境下这话是什么意思」。如果一个人在屋里说「这有点冷」,他的句法是在陈述温度事实,但他的语用意图通常是「请把窗户关上」。如果按照 Suggger 的逻辑,这个人就是在「逃避直接下达关窗指令的责任」?不,这只是人类社会通用的社交礼仪。</p>
<p>同样的道理,如果不考虑文化语境,单纯看语法,我们再回头看看 Suggger 眼中那个「直球、裸露、高效」的英语世界。他认为英文的肯定是分类、非黑即白的。这个观点忽略了英语中非常重要的修辞手法 ——Litotes(反语 / 低调陈述)。</p>
<p>英语也不是永远都在直球地进行属性赋值。它同样在大量使用「负向肯定」:</p>
<ul>
<li>I wouldn't say no = Yes, please</li>
<li>I don't disagree = I agree</li>
<li>It was no small feat = It was a huge achievement</li>
<li>Can't complain = Everything is good</li>
</ul>
<p>再用「不错」这个例子来说,Suggger 认为这是「避免承诺完美」。但在英语母语者的语境里(特别是英国人),当他们看着一份很棒的报告说 <em>Not bad at all</em> 时,这也往往是极高的赞赏,等同于 <em>Very good</em>。</p>
<p>这里的逻辑并不是「我在逃避给它打满分的责任」,而是「我通过压低预期的表达,来显得更客观或更谦虚」。</p>
<p>因为过度的赞美往往听起来像廉价的恭维,而克制的 <em>Not bad</em> 则暗示了说话者拥有极高的标准 —— 这意味着你的作品经受住了挑剔眼光的审视。这种「否定之否定」剔除了情绪化的泡沫,反而让赞美显得更加诚恳且更有分量。</p>
<p>更有趣的是,他声称英语强迫人们「公开立场」,但这恰恰忽略了英语语法中的 <u>主体消除</u>。当一个美国政客想要逃避责任时,他不需要像中国人那样用「原则上」这种模糊词,他只需要使用被动语态:<em>Mistakes were made</em>(错误已被铸成)。注意到了吗?在这个句子里,「错误」发生了,但「犯错的人」在语法层面上被直接删除了。这难道不是英语的「虚空」吗?</p>
<p>所以,如果因为中文里有「不错」,就认为中国人缺乏担当,那我也可以因为英文里有 <em>I wouldn't say no</em>,而论证讲英语的人都是一群首鼠两端之徒。这显然是荒谬的。</p>
<p>这种语言宿命论在流行文化中很受欢迎,因为它提供了一种廉价的深刻 —— 似乎只要破解了语法,就能看透一个民族的灵魂。Suggger 在文章中使用了编程逻辑:中文是 <code>!False</code>,英文是 <code>True</code>。这种极客式的比喻很容易让人产生「洞察了本质」的错觉。但看看上面那些日本人和英国人的例子,语言真的是冰冷的二进制代码吗?显然不是,语言是流动的博弈。</p>
<p>因此,无论是日语中不得不用的语法规则,还是中文里为了社交润滑的修辞选择,如果仅仅因为它们都带有「否定」成分,就将其统一解读为「避险心机」,会忽略语言演变的历史脉络,以及使用者在具体语境中的能动性。</p>
<p>这类理论之所以迷人,我认为这是因为它提供了一个简单化的诱惑:分析几个单词语法来解码整个庞大文明的底层逻辑。但是像我先前说的那样,<strong>语言不是冰冷的代码,是人类为了在复杂社会中生存而打磨出的工具</strong>。真正的洞察不应该止步于语法的表象,而应该去接触那些隐藏在单词背后、更为深沉的文化脉搏。</p>
<p>说到底,<strong>复杂的文化心理怎么可能塞得进去那小小的二进制框架呢?</strong></p>
</body></html></div></article></div></main><footer><div class="paginator"><a class="prev" href="7240.html">上一篇</a><a class="next" href="5097.html">下一篇</a></div><!-- Webmention 显示区域--><div class="webmention-section webmention-empty" data-page-url="posts/6e69.html" data-full-url="https://cytrogen.icu/posts/6e69.html" data-mode="static">
<h3 class="webmention-title">Webmentions (<span class="webmention-count">0</span>)</h3>
<div class="webmention-list"></div>
<span>暂无 Webmentions</span>
</div><div class="copyright"><p class="footer-links"><a href="../friends/index.html">友链</a><span class="footer-separator"> ·</span><a href="../links/index.html">邻邦</a><span class="footer-separator"> ·</span><a href="../contact/index.html">联络</a><span class="footer-separator"> ·</span><a href="../colophon/index.html">营造记</a><span class="footer-separator"> ·</span><a href="../atom.xml">RSS订阅</a></p><p>© 2025 - 2026 <a href="https://cytrogen.icu">Cytrogen</a>, powered by <a href="https://hexo.io/" target="_blank">Hexo</a> and <a href="https://github.com/cytrogen/hexo-theme-ares" target="_blank">hexo-theme-ares</a>.</p><p><a href="https://blogscn.fun" target="_blank" rel="noopener">BLOGS·CN</a></p></div></footer></div></div><a class="back-to-top" href="#top" aria-label="返回顶部"><svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M3.293 9.707a1 1 0 010-1.414L9.586 2a2 2 0 012.828 0l6.293 6.293a1 1 0 01-1.414 1.414L11 3.414V17a1 1 0 11-2 0V3.414L2.707 9.707a1 1 0 01-1.414 0z"></path></svg></a><script>document.addEventListener('DOMContentLoaded', function() {
const codeBlocks = document.querySelectorAll('figure.highlight');
codeBlocks.forEach(block => {
let caption = block.querySelector('figcaption');
if (!caption) {
caption = document.createElement('figcaption');
block.insertBefore(caption, block.firstChild);
}
const info = document.createElement('div');
info.className = 'info';
const filename = caption.querySelector('span');
if (filename) {
filename.className = 'filename';
info.appendChild(filename);
}
const lang = block.className.split(' ')[1];
if (lang) {
const langSpan = document.createElement('span');
langSpan.className = 'lang-name';
langSpan.textContent = lang;
info.appendChild(langSpan);
}
const sourceLink = caption.querySelector('a');
if (sourceLink) {
sourceLink.className = 'source-link';
info.appendChild(sourceLink);
}
const actions = document.createElement('div');
actions.className = 'actions';
const codeHeight = block.scrollHeight;
const threshold = 300;
if (codeHeight > threshold) {
block.classList.add('folded');
const toggleBtn = document.createElement('button');
toggleBtn.textContent = '展开';
toggleBtn.addEventListener('click', () => {
block.classList.toggle('folded');
toggleBtn.textContent = block.classList.contains('folded') ? '展开' : '折叠';
});
actions.appendChild(toggleBtn);
}
const copyBtn = document.createElement('button');
copyBtn.textContent = '复制';
copyBtn.addEventListener('click', async () => {
const codeLines = block.querySelectorAll('.code .line');
const code = Array.from(codeLines)
.map(line => line.textContent)
.join('\n')
.replace(/\n\n/g, '\n');
try {
await navigator.clipboard.writeText(code);
copyBtn.textContent = '已复制';
copyBtn.classList.add('copied');
setTimeout(() => {
copyBtn.textContent = '复制';
copyBtn.classList.remove('copied');
}, 3000);
} catch (err) {
console.error('复制失败:', err);
copyBtn.textContent = '复制失败';
setTimeout(() => {
copyBtn.textContent = '复制';
}, 3000);
}
});
actions.appendChild(copyBtn);
caption.innerHTML = '';
caption.appendChild(info);
caption.appendChild(actions);
const markedLines = block.getAttribute('data-marked-lines');
if (markedLines) {
const lines = markedLines.split(',');
lines.forEach(range => {
if (range.includes('-')) {
const [start, end] = range.split('-').map(Number);
for (let i = start; i <= end; i++) {
const line = block.querySelector(`.line-${i}`);
if (line) line.classList.add('marked');
}
} else {
const line = block.querySelector(`.line-${range}`);
if (line) line.classList.add('marked');
}
});
}
});
});</script><script async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script"></script><script>(function() {
document.addEventListener('DOMContentLoaded', function() {
const themeToggle = document.querySelector('.theme-toggle');
if (!themeToggle) return;
const getCurrentTheme = () => {
return document.documentElement.getAttribute('data-theme') || 'light';
};
const updateUI = (theme) => {
const isDark = theme === 'dark';
themeToggle.setAttribute('aria-pressed', isDark.toString());
};
const setTheme = (theme) => {
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
const pageWrapper = document.getElementById('page-wrapper');
if (pageWrapper) {
pageWrapper.setAttribute('data-theme', theme);
}
// Find and remove the temporary anti-flicker style tag if it exists.
// This ensures the main stylesheet takes full control after the initial load.
const antiFlickerStyle = document.getElementById('anti-flicker-style');
if (antiFlickerStyle) {
antiFlickerStyle.remove();
}
localStorage.setItem('theme', theme);
updateUI(theme);
};
const toggleTheme = () => {
const current = getCurrentTheme();
const newTheme = current === 'light' ? 'dark' : 'light';
setTheme(newTheme);
};
updateUI(getCurrentTheme());
themeToggle.addEventListener('click', toggleTheme);
if (window.matchMedia) {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
mediaQuery.addEventListener('change', function(e) {
if (!localStorage.getItem('theme')) {
const theme = e.matches ? 'dark' : 'light';
setTheme(theme);
}
});
}
});
})();
</script><script src="../js/details-toggle.js" defer></script><script>(function() {
document.addEventListener('DOMContentLoaded', function() {
const backToTopBtn = document.querySelector('.back-to-top');
if (!backToTopBtn) return;
const toggleButtonVisibility = () => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const shouldShow = scrollTop > 200;
if (shouldShow) {
backToTopBtn.classList.add('is-visible');
} else {
backToTopBtn.classList.remove('is-visible');
}
};
let ticking = false;
const handleScroll = () => {
if (!ticking) {
requestAnimationFrame(() => {
toggleButtonVisibility();
ticking = false;
});
ticking = true;
}
};
const scrollToTop = (event) => {
event.preventDefault();
window.scrollTo({
top: 0,
behavior: 'smooth'
});
};
window.addEventListener('scroll', handleScroll);
backToTopBtn.addEventListener('click', scrollToTop);
toggleButtonVisibility();
});
})();</script></body></html>