<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ceeji 篤志者 - 宁心勉学，慎思笃行</title><link>https://ceeji.net/zh-hant/</link><description>Recent content in Ceeji 篤志者 on 宁心勉学，慎思笃行</description><language>zh-hant</language><atom:link href="https://ceeji.net/zh-hant/index.xml" rel="self" type="application/rss+xml"/><item><title>紹興之旅（4）：陽明故里、沈園與書聖故里</title><link>https://ceeji.net/zh-hant/blog/travel-2024-04-shaoxing-4/</link><pubDate>Thu, 02 May 2024 16:08:56 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/travel-2024-04-shaoxing-4/</guid><description>&lt;p&gt;這次旅程的第四天，我主要去了紹興的陽明故里、沈園和書聖故里。&lt;/p&gt;
&lt;h2 id="此心光明陽明故里"&gt;此心光明——陽明故里&lt;/h2&gt;
&lt;p&gt;陽明故里是王守仁（即「王陽明」）的故居所在地，其建築已經只剩地基上一些樁石之類，現在看到的大多數內容是近幾年新建的。但是，它在考古挖掘的重點區域透過透明玻璃的方式保留了現場，因此你可以看到一些「真傢伙」。我去的時候剛好碰到政府的觀光團，有導遊隨行講解，也因此大致瞭解了王陽明相關的一些故事。整體而言，這個地方能看到的東西不多。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04742.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04742.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04742.jpg" type="image/jpeg"/&gt;&lt;img title="王陽明故居" alt="王陽明故居" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04742.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;王陽明故居&lt;/span&gt;&lt;span class="exif" title="21mm f/6.3 E 17-28mm F2.8-2.8 "&gt;21mm f/6.3 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04745.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04745.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04745.jpg" type="image/jpeg"/&gt;&lt;img title="王陽明故居玻璃下的考古現場" alt="王陽明故居玻璃下的考古現場" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04745.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;王陽明故居玻璃下的考古現場&lt;/span&gt;&lt;span class="exif" title="17mm f/2.8 E 17-28mm F2.8-2.8 "&gt;17mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;王陽明對死生非常豁達。據說其臨死前留下的遺言為：「此心光明，亦復何言？」&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04750.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04750.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04750.jpg" type="image/jpeg"/&gt;&lt;img title="此心光明" alt="此心光明" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04750.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;此心光明&lt;/span&gt;&lt;span class="exif" title="20mm f/2.8 E 17-28mm F2.8-2.8 "&gt;20mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;除了建築，這個景點還有一個王陽明的紀念館。但是裡面的東西不是很多。看完陽明故里，我就抓緊趕往沈園，因為此刻已經是下午三四點鐘。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04785.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04785.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04785.jpg" type="image/jpeg"/&gt;&lt;img title="去沈園步行路上" alt="去沈園步行路上" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04785.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;去沈園步行路上&lt;/span&gt;&lt;span class="exif" title="27mm f/2.8 E 17-28mm F2.8-2.8 "&gt;27mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04786.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04786.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04786.jpg" type="image/jpeg"/&gt;&lt;img title="沈園門口的小河" alt="沈園門口的小河" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04786.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;沈園門口的小河&lt;/span&gt;&lt;span class="exif" title="27mm f/2.8 E 17-28mm F2.8-2.8 "&gt;27mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;h2 id="沈園"&gt;沈園&lt;/h2&gt;
&lt;p&gt;昨天我去看了&lt;a href="../travel-2024-04-shaoxing-ningbo-3/"&gt;沈園之夜&lt;/a&gt;，今天繼續來看白天的沈園。沈園也是建國後重修的，在門口有重修之記。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04814.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04814.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04814.jpg" type="image/jpeg"/&gt;&lt;img title="重建沈園碑記" alt="重建沈園碑記" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04814.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;重建沈園碑記&lt;/span&gt;&lt;span class="exif" title="24mm f/2.8 E 17-28mm F2.8-2.8 "&gt;24mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;沈園的名氣幾乎全依賴於陸游在此的故事。簡單來說，陸游在父母的安排下，迎娶表妹唐婉為妻。兩人的婚姻雖然是父母之命媒妁之言的老式婚姻，可是卻超乎尋常的幸福。陸游的母親唐氏本是這場婚姻的主導者，可是，在唐婉過門之後不到三年，唐氏就對自己的侄女唐婉厭惡不已，強逼著兒子把唐婉趕走。主要原因一是覺得陸游沉湎女色，不務正業，讓父母焦慮不安。另一個原因，可能是唐婉不孕。古人多希望「早生貴子」，像陸游續娶王氏，次年就生了一個大胖小子。可唐婉婚後兩年多，肚皮竟然一點訊息也沒有。這在古代可是「七出」之首的嚴重罪過。&lt;/p&gt;
&lt;p&gt;於是，唐婉就有了兩大罪名：讓陸游倦於科舉，影響仕途；婚後三年不孕，不能傳宗接代。最終，陸母下令，將唐婉驅逐出陸家家門。&lt;/p&gt;
&lt;p&gt;在31歲時，陸游偶然在春末遊覽沈園，巧遇唐婉，回想起過往種種，在沈園的牆壁上寫下流傳千古的《釵頭鳳》，表達自己的愁緒。據說後續唐婉也回詩一首，詞牌也是「釵頭鳳」。&lt;/p&gt;
&lt;p&gt;但這個故事的真實性我覺得很難說，很多細節在史料中沒有證據。甚至有人認為唐婉這個名字是明清時編出來的，而且唐嫁也沒嫁趙士程，趙士程是有老婆陳氏的，還有六個孩子，沒了一個，剩下五個。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04825.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04825.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04825.jpg" type="image/jpeg"/&gt;&lt;img title="沈園中的兩首釵頭鳳" alt="沈園中的兩首釵頭鳳" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04825.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;沈園中的兩首釵頭鳳&lt;/span&gt;&lt;span class="exif" title="17mm f/2.8 E 17-28mm F2.8-2.8 "&gt;17mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;沈園的風景是典型的江南園林。在入口有一塊斷了的石頭，據說象徵情緣斷裂，我好奇這石頭是不是重建沈園的時候專門找人砸開的？&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04787.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04787.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04787.jpg" type="image/jpeg"/&gt;&lt;img title="斷石" alt="斷石" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04787.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;斷石&lt;/span&gt;&lt;span class="exif" title="27mm f/2.8 E 17-28mm F2.8-2.8 "&gt;27mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;沈園的面積不小，重修經歷了好幾期，現在如果要全部轉完需要點時間。裡面有一個陸游的紀念館，僅僅這一個紀念館面積就不小。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04822.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04822.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04822.jpg" type="image/jpeg"/&gt;&lt;img title="陸游紀念館最深處" alt="陸游紀念館最深處" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04822.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;陸游紀念館最深處&lt;/span&gt;&lt;span class="exif" title="24mm f/2.8 E 17-28mm F2.8-2.8 "&gt;24mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="書聖故里"&gt;書聖故里&lt;/h2&gt;
&lt;p&gt;我以為書聖故里是王羲之的某個故居之類，沒想到又是一個歷史街區，主要是古橋和古建築。其中比較有名的是題扇橋。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04875.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04875.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04875.jpg" type="image/jpeg"/&gt;&lt;img title="書聖故里" alt="書聖故里" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04875.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;書聖故里&lt;/span&gt;&lt;span class="exif" title="24mm f/2.8 E 17-28mm F2.8-2.8 "&gt;24mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04881.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04881.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04881.jpg" type="image/jpeg"/&gt;&lt;img title="題扇橋" alt="題扇橋" src="https://ceeji.net/blog/travel-2024-04-shaoxing-4/DSC04881.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;題扇橋&lt;/span&gt;&lt;span class="exif" title="20mm f/2.8 E 17-28mm F2.8-2.8 "&gt;20mm f/2.8 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>紹興之旅（3）：蘭亭景區、印山越國王陵、八字橋周邊與沈園之夜</title><link>https://ceeji.net/zh-hant/blog/travel-2024-04-shaoxing-ningbo-3/</link><pubDate>Tue, 30 Apr 2024 22:54:44 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/travel-2024-04-shaoxing-ningbo-3/</guid><description>&lt;h2 id="蘭亭景區"&gt;蘭亭景區&lt;/h2&gt;
&lt;p&gt;因為公司有事，我在4月10日回到杭州處理事情。第二天，我重新出發踏上了旅途。這一次，我先來到了紹興蘭亭景區，這裡主要是一些與王羲之有關的人文景觀，其中最多的就是各種書法作品的石刻和亭臺樓閣。據說「蘭亭集序」就是王羲之在這裡所寫就。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04350.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04350.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04350.jpg" type="image/jpeg"/&gt;&lt;img title="蘭亭入口" alt="蘭亭入口" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04350.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;蘭亭入口&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;進入景區不久就是「鳶（yuān）池」，裡面似乎養了幾隻鳶，但我並不知道「鳶」到底是什麼，查了一下資料依然是雲裡霧裡。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04363.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04363.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04363.jpg" type="image/jpeg"/&gt;&lt;img title="鳶池書法" alt="鳶池書法" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04363.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;鳶池書法&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04364.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04364.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04364.jpg" type="image/jpeg"/&gt;&lt;img title="鳶池的「鳶」" alt="鳶池的「鳶」" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04364.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;鳶池的「鳶」&lt;/span&gt;&lt;span class="exif" title="56mm f/4.0 FE 24-105mm F4 G OSS "&gt;56mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;這裡有一塊康熙寫的「蘭亭」的碑，但在文化大革命中被損壞，成為殘字。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04368.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04368.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04368.jpg" type="image/jpeg"/&gt;&lt;img title="「蘭亭」碑亭" alt="「蘭亭」碑亭" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04368.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;「蘭亭」碑亭&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;與之前一樣，我並沒有提前做什麼功課，但我剛好碰到了它的「書聖節」，就是每年一度紀念王羲之以及舉行一些書法活動的節日。因此，景區里人比較多，而且到處都是活動相關的內容。下面這張圖的橫幅就是活動所懸掛的，這裡在我來之前不久剛舉辦過晉聖儀式。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04369.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04369.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04369.jpg" type="image/jpeg"/&gt;&lt;img title="晉聖儀式" alt="晉聖儀式" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04369.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;晉聖儀式&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;在這個地方不遠處就是傳說中「九曲流觴」之地。一千年前，古人喜歡圍坐在這樣的小溪流邊，放入酒杯，讓酒杯順水而流，流到誰那裡就要作詩作文。而此刻，這個地方有幾個外國留學生說著流利的中文在討論問題。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04372.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04372.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04372.jpg" type="image/jpeg"/&gt;&lt;img title="流觴亭" alt="流觴亭" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04372.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;流觴亭&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04374.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04374.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04374.jpg" type="image/jpeg"/&gt;&lt;img title="九曲流觴之地" alt="九曲流觴之地" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04374.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;九曲流觴之地&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;整個蘭亭景區最多的就是「蘭亭集序」，比如這裡有一個非常高大的蘭亭集序的書法碑文：&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04376.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04376.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04376.jpg" type="image/jpeg"/&gt;&lt;img title="蘭亭集序" alt="蘭亭集序" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04376.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;蘭亭集序&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;由於書聖節，這裡還在舉辦全國書法篆刻的展覽。我進去簡單看了一下，名家所寫確實好看！我最喜歡的是下圖中間的這一張：&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04588.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04588.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04588.jpg" type="image/jpeg"/&gt;&lt;img title="書法篆刻展覽" alt="書法篆刻展覽" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04588.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;書法篆刻展覽&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="印山越國王陵"&gt;印山越國王陵&lt;/h2&gt;
&lt;p&gt;看完了蘭亭景區，我馬不停蹄地趕往旁邊不遠處地「印山越國王陵」。到了門口正好是下午4點整，停好車進去是4點2分的樣子，保安不讓進，說4點開始禁止進入，4點半停止營業。我執意要進，最後允許我進去了。這裡是一個考古發現，發現的時間距今也不過二三十年。這個景區名氣不太大，我是因為看地圖發現的。這個陵墓缺乏直接的證據證明墓主人的身份，但據推測極有可能是越王勾踐之父允常。這個王陵曾經在抖音上火過。&lt;/p&gt;
&lt;p&gt;景區十分精簡，在國內這種景區其實是不多見的。停車場就是一片土地，真的就只有土。而景區的入口旁邊就是大片的農田。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04628.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04628.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04628.jpg" type="image/jpeg"/&gt;&lt;img title="印山越國王陵" alt="印山越國王陵" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04628.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;印山越國王陵&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;在現場我看到了「木客大冢」四個大字，當時完全不明白是什麼意思，看到上面有一隻鳥的形狀，更是非常神秘。後來查維基百科才知道這個地方在當地最初被稱為「木客大冢」，因其所在地原為木客的聚居地而得名，是一座人工堆築的大型古代墓葬。而這個山「印山」以前也叫「木客山」。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04614.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04614.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04614.jpg" type="image/jpeg"/&gt;&lt;img title="「木客大冢」" alt="「木客大冢」" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04614.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;「木客大冢」&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;隨著階梯進入王陵內部後，又有一個保安看到了我，不耐煩地說快要下班了，讓我不要進去。明明還有半個小時時間，王陵也很小，我就執意要進去。說真的，親眼見到王陵還是挺壯觀的，不虛此行。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04598.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04598.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04598.jpg" type="image/jpeg"/&gt;&lt;img title="王陵內部" alt="王陵內部" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04598.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;王陵內部&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04603.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04603.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04603.jpg" type="image/jpeg"/&gt;&lt;img title="王陵內部" alt="王陵內部" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04603.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;王陵內部&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04612.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04612.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04612.jpg" type="image/jpeg"/&gt;&lt;img title="王陵內部" alt="王陵內部" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04612.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;王陵內部&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;有時候，不做規劃的旅行最容易出現驚喜。在印山越國王陵，我沒有見到一個遊人，且天色已晚，又是強行進入，保安一直催，我本來並不覺得能看到什麼東西。但我不但完整地看到了王陵內部，而且在往出口的時候偶然在地圖上發現徐渭的墓地也在這個園區之中，於是躲過保安從山上小路直奔徐渭之墓。我基本不瞭解徐渭，一邊走一邊在網上簡單瞭解了一下，知道他是明代中期的文學家和軍事家。&lt;/p&gt;
&lt;p&gt;路上經過一個私人的魚塘，讓人一度懷疑自己是不是還在景區之中。名字也十分有意思，叫「塘狗弄山塘」。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04617.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04617.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04617.jpg" type="image/jpeg"/&gt;&lt;img title="塘狗弄山塘" alt="塘狗弄山塘" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04617.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;塘狗弄山塘&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;整個景區道路都人跡罕至，但標牌還比較清楚，而且路上竟然遇到了兩三個剛從徐渭墓地出來的人。我加快了腳步，因為馬上就四點半了，我想我估計進不去了。路上我路過一個指路牌，感覺字寫得很有設計感，尤其是「渭」和「園」字格外好看，整體看也很莊重，於是拍了下來。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04619.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04619.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04619.jpg" type="image/jpeg"/&gt;&lt;img title="「徐渭墓園」路牌" alt="「徐渭墓園」路牌" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04619.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;「徐渭墓園」路牌&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;快到的時候，路邊種滿了很小的松樹，雖然不大但依然給人蒼勁嚴肅之感，再加上四處寧靜無人，氣氛渲染的非常空靈。可惜的是，我還是沒能進去，只能從墓園的門口遙望。可以感知的是，墓園內樹木極多，花草繁茂。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04624.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04624.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04624.jpg" type="image/jpeg"/&gt;&lt;img title="去墓園的路上" alt="去墓園的路上" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04624.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;去墓園的路上&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04623.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04623.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04623.jpg" type="image/jpeg"/&gt;&lt;img title="徐渭墓園" alt="徐渭墓園" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04623.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;徐渭墓園&lt;/span&gt;&lt;span class="exif" title="24mm f/4.0 FE 24-105mm F4 G OSS "&gt;24mm f/4.0 FE 24-105mm F4 G OSS&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;h2 id="八字橋周邊"&gt;八字橋周邊&lt;/h2&gt;
&lt;p&gt;看完徐渭墓，我開車直奔八字橋，此時天色開始漸漸下雨。因為擔心停車難，我把車停到了大概 1 公里外的一個停車場充電，然後步行前往八字橋周邊。在來這裡之前，我完全不清楚這裡是什麼。快到終點的時候，看到了一個天主教堂。再走幾步路，八字橋映入眼簾，我才發現這裡比我想象的要值得來看很多。幾個詞總結——純天然、很乾淨、大面積、江南煙雨。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04638.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04638.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04638.jpg" type="image/jpeg"/&gt;&lt;img title="天主教堂" alt="天主教堂" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04638.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;天主教堂&lt;/span&gt;&lt;span class="exif" title="35mm f/1.4 FE 35mm F1.4 GM "&gt;35mm f/1.4 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04639.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04639.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04639.jpg" type="image/jpeg"/&gt;&lt;img title="八字橋之牌" alt="八字橋之牌" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04639.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;八字橋之牌&lt;/span&gt;&lt;span class="exif" title="35mm f/1.4 FE 35mm F1.4 GM "&gt;35mm f/1.4 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;具體來說，這是一大片保留非常好的傳統街區，有橋有水、建築優美，商業化程度剛剛好，且原住民非常多。隨便走走就能走到別人家裡。因為剛好下雨，從橋上遠眺，一片江南煙雨。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04733.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04733.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04733.jpg" type="image/jpeg"/&gt;&lt;img title="江南煙雨" alt="江南煙雨" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04733.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;江南煙雨&lt;/span&gt;&lt;span class="exif" title="35mm f/1.4 FE 35mm F1.4 GM "&gt;35mm f/1.4 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04647.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04647.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04647.jpg" type="image/jpeg"/&gt;&lt;img title="八字橋周邊" alt="八字橋周邊" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04647.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;八字橋周邊&lt;/span&gt;&lt;span class="exif" title="35mm f/2.0 FE 35mm F1.4 GM "&gt;35mm f/2.0 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04650.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04650.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04650.jpg" type="image/jpeg"/&gt;&lt;img title="八字橋與水上烏篷船" alt="八字橋與水上烏篷船" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04650.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;八字橋與水上烏篷船&lt;/span&gt;&lt;span class="exif" title="35mm f/2.0 FE 35mm F1.4 GM "&gt;35mm f/2.0 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;走在其中，商業氣息不是很濃，且移步換景。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;&lt;figure&gt;
&lt;a href="DSC04651.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04651.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04651.jpg" type="image/jpeg"/&gt;&lt;img title="" alt="" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04651.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04657.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04657.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04657.jpg" type="image/jpeg"/&gt;&lt;img title="" alt="" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04657.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;從一個小巷中出來還有一個漂亮的寺廟。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;a href="DSC04661.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04661.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04661.jpg" type="image/jpeg"/&gt;&lt;img title="" alt="" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04661.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="沈園之夜"&gt;沈園之夜&lt;/h2&gt;
&lt;p&gt;沈園即「沈氏園」，是紹興的一個園林。裡面流傳著陸游的一個感情故事。這個景區做了一個晚上看的劇目「沈園之夜」，我趁著夜色把它給看了。我本來一度認為今天看不成了，因為當時雨下的挺大，但到了演出快開始的時候，雨差不多停了。我也剛好在演出開始前兩三分鐘才趕到了沈園。&lt;/p&gt;
&lt;p&gt;但我認為這個劇寫的不好，演的也一般。其實這個劇目確實也不好演，因為沈園之夜顯然主要是說沈園，但陸游的這個感情故事，應該只有幾個片段發生在沈園，大多數時候和沈園關係不大。在劇目中，硬生生被描繪成發生在沈園的故事，這在邏輯上有點怪。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04736.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04736.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04736.jpg" type="image/jpeg"/&gt;&lt;img title="沈園之夜" alt="沈園之夜" src="https://ceeji.net/blog/travel-2024-04-shaoxing-ningbo-3/DSC04736.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;沈園之夜&lt;/span&gt;&lt;span class="exif" title="35mm f/1.4 FE 35mm F1.4 GM "&gt;35mm f/1.4 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>結合 TextRank 與 TF-IDF 更精準的提取文章關鍵詞</title><link>https://ceeji.net/zh-hant/blog/combine-tf-idf-text-rank/</link><pubDate>Tue, 30 Apr 2024 18:50:40 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/combine-tf-idf-text-rank/</guid><description>&lt;p&gt;我們往往需要從大量的文字中迅速提取出核心關鍵詞，以便快速把握文章主旨。如果要做資訊流分發、基於內容的推薦演算法，這也是其中很重要的步驟，一般用於文章特徵。&lt;/p&gt;
&lt;p&gt;傳統的 TF-IDF 方法雖然廣泛使用，但有時候它並不能完全準確地反映出文章的關鍵內容。實際上，TextRank、PositionRank 等任意演算法都很難保證不遺漏重要的關鍵詞。為了提高關鍵詞提取的準確性，我們可以採用結合多種演算法的方式來提取關鍵詞。我在產品中使用了 TextRank 演算法和 TF-IDF 的方法來結合，實測效果不錯。&lt;/p&gt;
&lt;p&gt;不同的庫實現的關鍵詞提取，結果往往不同，因為其實現細節有優劣之分。這裡我使用的是 &lt;code&gt;pke_zh&lt;/code&gt; 和 &lt;code&gt;textrank4zh&lt;/code&gt; 庫，透過 Python 程式碼實現這一過程。&lt;/p&gt;
&lt;p&gt;在介紹程式碼實現之前，我們先簡單回顧一下 TF-IDF 和 TextRank 的基本概念。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TF-IDF&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;TF-IDF&lt;/code&gt;（詞頻-逆文件頻率）是一種用於資訊檢索與文字挖掘的常用加權技術。它透過計算詞語的頻率（TF）和其在文件集中的分佈（IDF）來評估一個詞語對於一個檔案集或一個語料庫中的其中一份檔案的重要程度。TF-IDF 值越大，這個詞在文字中的重要性越高。&lt;/p&gt;
&lt;p&gt;你可以在&lt;a href="../%e7%99%be%e5%ba%a6noip%e5%90%a7%e7%bc%96%e7%a8%8b%e6%8c%91%e6%88%98%e8%b5%9b%e9%98%b2%e4%bd%9c%e5%bc%8a%e7%b3%bb%e7%bb%9f%ef%bc%9a%e5%9f%ba%e4%ba%8e%e5%90%91%e9%87%8f%e7%a9%ba%e9%97%b4%e6%b3%95/"&gt;這篇文章&lt;/a&gt;檢視具體的計算方法和公式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TextRank&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;TextRank 是一種基於圖的排序演算法，透過將文字分割成多個單詞，並將這些單詞作為圖中的節點，透過節點之間的相互影響，計算每個節點的重要性。在關鍵詞提取的場景中，TextRank 可以幫助我們找出文字中的高權重關鍵詞。&lt;/p&gt;
&lt;p&gt;接下來，我們將詳細講解如何使用程式碼實現更精準的關鍵詞提取。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;文字預處理&lt;/strong&gt;：首先，我們將文字轉換為小寫，並使用正則表示式移除所有的數字，這是為了確保後續處理的文字是純粹的文字資料。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;關鍵詞提取&lt;/strong&gt;：我們使用 &lt;code&gt;TfIdf_m.extract&lt;/code&gt; 方法和 &lt;code&gt;tr4w.analyze&lt;/code&gt; 方法分別提取 TF-IDF 和 TextRank 的結果。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;關鍵詞合併與向量生成&lt;/strong&gt;：將兩種方法提取的關鍵詞合併，併為每個關鍵詞生成相應的 TF-IDF 和 TextRank 向量。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;資料歸一化&lt;/strong&gt;：為了使不同的指標具有可比性，我們使用 &lt;code&gt;MinMaxScaler&lt;/code&gt; 對資料進行歸一化處理。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;混合向量計算&lt;/strong&gt;：將歸一化後的 TF-IDF 向量和 TextRank 向量按照一定的比例混合，從而得到一個綜合考慮兩者的混合向量。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;關鍵詞排序&lt;/strong&gt;：根據混合向量的值對關鍵詞進行排序，並選出排名前20的關鍵詞作為最終的關鍵詞。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;完整程式碼如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pke_zh&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TextRank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TfIdf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PositionRank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Yake&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;KeyBert&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;codecs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;timeit&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;default_timer&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MinMaxScaler&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;textrank4zh&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TextRank4Keyword&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;TfIdf_m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TfIdf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tr4w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextRank4Keyword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_keywords_mixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 轉換為小寫&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 使用正則移除所有純數字，包括整數和小數&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\b\d+(\.\d+)?\b&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 獲取初始 tf-idf 和 textrank 資料&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tfidf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TfIdf_m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_best&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tr4w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;analyze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;textrank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tr4w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_keywords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word_min_len&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;textrank&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 合併關鍵詞清單&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;allKeywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tfidf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;allKeywords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;textrank&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;allKeywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;allKeywords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 根據合併的關鍵詞清單重新生成 tfidf 和 textrank 向量，對原始不存在的資料使用 0 填充&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tfidf_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;textrank_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;allKeywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tfidf_vector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tfidf&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tfidf&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;textrank_vector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;textrank&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;textrank&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 資料歸一化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;scaler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MinMaxScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tfidf_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tfidf_vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reshape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tfidf_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tfidf_vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;textrank_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;textrank_vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reshape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;textrank_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scaler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;textrank_vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 混合向量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;mixed_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tfidf_vector&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;textrank_vector&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 加入關鍵詞名稱&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;mixed_keywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allKeywords&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;mixed_keywords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mixed_vector&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 獲取前 top 個關鍵詞&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;mixed_keywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mixed_keywords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;mixed_keywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mixed_keywords&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mixed_keywords&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mixed_keywords&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;透過結合 TF-IDF 和 TextRank 演算法，我們可以更全面地考慮詞語的重要性和文字結構，從而提高關鍵詞提取的準確性。以上程式碼實現了一個基於這兩種技術的混合關鍵詞提取方法，有助於我們在實際應用中抽取出更加精準的關鍵資訊。&lt;/p&gt;</description></item><item><title>紹興之旅（2）：會稽山兜率天、倉橋直街與魯迅故居</title><link>https://ceeji.net/zh-hant/blog/travel-2024-04-shaoxing-2/</link><pubDate>Mon, 29 Apr 2024 23:29:33 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/travel-2024-04-shaoxing-2/</guid><description>&lt;h2 id="會稽山兜率天"&gt;會稽山兜率天&lt;/h2&gt;
&lt;p&gt;會稽山是紹興名山，在中國歷史上也有重要地位，後面我們還會多次提到這座山。雖然如此，但我此次來到會稽山並沒有什麼準備。當時我在前一天晚上看過柯橋古鎮之後，就在地圖上尋找附近可去的地方，發現了「會稽山兜率天景區」的字樣，然後在網上簡單搜了幾句就決定第二天過去看看。我感覺，「會稽山」是一大片山脈，因為還有其他地方也屬於會稽山。&lt;/p&gt;
&lt;p&gt;這個地方的第一印象並不好，因為我不喜歡被強迫要求坐景區大巴上山，但也沒有辦法。上山之後我發現這個景區有個特別之處——景區大巴直接把我拉到了靠近山頂的地方，而且下車後先進入了一個建築之內，裡面全是紀念品商店。一般景區的紀念品商店都在出口，它卻在入口。另外，走過紀念品商店後，需要坐好幾層的電梯，然後會到達一個十分寬闊恢弘的平臺，平臺盡頭就是景區的第一個主要景點——龍華寺。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04213.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04213.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04213.jpg" type="image/jpeg"/&gt;&lt;img title="龍華寺" alt="龍華寺" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04213.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;龍華寺&lt;/span&gt;&lt;span class="exif" title="17mm f/8.0 E 17-28mm F2.8-2.8 "&gt;17mm f/8.0 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;龍華寺的牌坊十分大氣和恢弘，我使用&lt;code&gt;騰龍 17-28mm 鏡頭&lt;/code&gt;超廣角拍攝下來效果十分震撼（上圖），驚訝到我了，在這之前我除了拍攝星空，很少使用這顆鏡頭的 17mm 端。&lt;/p&gt;
&lt;p&gt;接下來是同樣震撼的大殿和其屋簷：&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04226.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04226.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04226.jpg" type="image/jpeg"/&gt;&lt;img title="大雄寶殿" alt="大雄寶殿" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04226.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;大雄寶殿&lt;/span&gt;&lt;span class="exif" title="28mm f/8.0 E 17-28mm F2.8-2.8 "&gt;28mm f/8.0 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04215.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04215.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04215.jpg" type="image/jpeg"/&gt;&lt;img title="超廣角下的屋簷" alt="超廣角下的屋簷" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04215.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;超廣角下的屋簷&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;龍華寺建築精美，但除此之外乏善可陳。走過龍華寺的幾個大殿之後，我遠遠看到了景區主打的標誌性景觀「兜率天宮」。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04244.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04244.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04244.jpg" type="image/jpeg"/&gt;&lt;img title="遠眺兜率天宮" alt="遠眺兜率天宮" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04244.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;遠眺兜率天宮&lt;/span&gt;&lt;span class="exif" title="20mm f/9.0 E 17-28mm F2.8-2.8 "&gt;20mm f/9.0 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;「兜率天」是梵文 &lt;code&gt;Tusita&lt;/code&gt; 的音譯，也譯成「兜率陀」。六慾天之一。此天有內、外兩院，內院是彌勒居住的淨土，普通訊眾若信仰彌勒，稱誦其名號，死後便可往生（即上生）此天。&lt;/p&gt;
&lt;p&gt;這也是一個人工建築，完工於 2015 年。兜率天作為佛教極樂淨土的所在，之前只存在於宗教典籍之中。提出修建該建築的是潘建國先生（國學大師南懷瑾先生的弟子），用於教化與文化傳播，吸引大量遊客前往，利於佛教文化傳播。按照《彌勒上生經》中善財童子參彌勒的描述，他提取出兜率天宮的主要元素——寶宮形態像須彌山，山下有香水海、七重寶垣，蓮花也是兜率天宮必不可少的重要特徵。&lt;/p&gt;
&lt;p&gt;在去往兜率天宮的路上，需要先下山，然後再爬山，最後到達刻有名字的石頭。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04246.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04246.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04246.jpg" type="image/jpeg"/&gt;&lt;img title="兜率天宮石刻" alt="兜率天宮石刻" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04246.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;兜率天宮石刻&lt;/span&gt;&lt;span class="exif" title="20mm f/9.0 E 17-28mm F2.8-2.8 "&gt;20mm f/9.0 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;近觀兜率天宮，發現其中分很多層，建築外側是非常恢弘的階梯，在中間一層正在進行陶瓷藝術品展覽，標價不菲。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04248.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04248.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04248.jpg" type="image/jpeg"/&gt;&lt;img title="兜率天宮" alt="兜率天宮" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04248.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;兜率天宮&lt;/span&gt;&lt;span class="exif" title="28mm f/9.0 E 17-28mm F2.8-2.8 "&gt;28mm f/9.0 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04252.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04252.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04252.jpg" type="image/jpeg"/&gt;&lt;img title="兜率天宮內部" alt="兜率天宮內部" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04252.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;兜率天宮內部&lt;/span&gt;&lt;span class="exif" title="17mm f/4.0 E 17-28mm F2.8-2.8 "&gt;17mm f/4.0 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04262.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04262.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04262.jpg" type="image/jpeg"/&gt;&lt;img title="兜率天宮頂部" alt="兜率天宮頂部" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04262.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;兜率天宮頂部&lt;/span&gt;&lt;span class="exif" title="18mm f/6.3 E 17-28mm F2.8-2.8 "&gt;18mm f/6.3 E 17-28mm F2.8-2.8&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;從兜率天宮下來，我想再去它的另一個景點「大香林」看看，但時間已經十分緊張。我沿著山路抄小道一路走過去，大概用了半個多小時，一路上全是筍，十分壯觀。到了大香林後發現這裡並沒有什麼太多東西，只有一些古樹。因為景區即將關門，我匆匆看了幾眼就直接走了。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04290.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04290.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04290.jpg" type="image/jpeg"/&gt;&lt;img title="大香林景區的繡球花" alt="大香林景區的繡球花" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04290.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;大香林景區的繡球花&lt;/span&gt;&lt;span class="exif" title="50mm f/6.3 E 50-400mm F4.5-6.3 A067 "&gt;50mm f/6.3 E 50-400mm F4.5-6.3 A067&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;離開會稽山兜率天后，在路上看到好幾個「黃酒小鎮」的牌子，網上查了一下似乎是一個值得去的地方，於是跟著標誌停車，停好車後才發現被騙了——這個「黃酒小鎮」實則為酒廠。裡面還煞有介事地搞了個黃酒博物館。搞笑的是，在地圖上，黃酒小鎮和黃酒博物館都存在，但位置是距離這裡十幾公里的越城區；而這裡所謂的的「黃酒小鎮」和「黃酒博物館」，地圖上完全沒有標誌。不過，這裡的風景還不錯，裡面有一整牆的李白將進酒的詩句，還做了一些愛喝酒的古人的塑像。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04298.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04298.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04298.jpg" type="image/jpeg"/&gt;&lt;img title="所謂「黃酒小鎮」" alt="所謂「黃酒小鎮」" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04298.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;所謂「黃酒小鎮」&lt;/span&gt;&lt;span class="exif" title="35mm f/8.0 FE 35mm F1.4 GM "&gt;35mm f/8.0 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04296.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04296.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04296.jpg" type="image/jpeg"/&gt;&lt;img title="所謂「黃酒博物館」" alt="所謂「黃酒博物館」" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04296.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;所謂「黃酒博物館」&lt;/span&gt;&lt;span class="exif" title="35mm f/8.0 FE 35mm F1.4 GM "&gt;35mm f/8.0 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04293.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04293.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04293.jpg" type="image/jpeg"/&gt;&lt;img title="愛酒之人塑像" alt="愛酒之人塑像" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04293.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;愛酒之人塑像&lt;/span&gt;&lt;span class="exif" title="35mm f/4.0 FE 35mm F1.4 GM "&gt;35mm f/4.0 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;h2 id="魯迅故里附近"&gt;魯迅故里附近&lt;/h2&gt;
&lt;p&gt;離開「黃酒小鎮」附近後，我一路直奔魯迅故里附近。這附近我已經來過幾次，但因為是紹興最經典的一片區域，我還是決定在附近轉轉，倒不是一定要進入核心景點，更多的是要在附近的步行街轉轉，感受一下。把車停好充電後，我來到了魯迅故里步行街的核心位置，這裡有一家王奶奶臭豆腐，我吃了感覺還挺不錯。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04299.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04299.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04299.jpg" type="image/jpeg"/&gt;&lt;img title="魯迅故里步行街牌坊" alt="魯迅故里步行街牌坊" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04299.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;魯迅故里步行街牌坊&lt;/span&gt;&lt;span class="exif" title="35mm f/4.0 FE 35mm F1.4 GM "&gt;35mm f/4.0 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04301.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04301.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04301.jpg" type="image/jpeg"/&gt;&lt;img title="王奶奶臭豆腐" alt="王奶奶臭豆腐" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04301.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;王奶奶臭豆腐&lt;/span&gt;&lt;span class="exif" title="35mm f/3.2 FE 35mm F1.4 GM "&gt;35mm f/3.2 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04305.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04305.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04305.jpg" type="image/jpeg"/&gt;&lt;img title="附近的餐飲店及烏篷船專用河" alt="附近的餐飲店及烏篷船專用河" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04305.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;附近的餐飲店及烏篷船專用河&lt;/span&gt;&lt;span class="exif" title="35mm f/3.2 FE 35mm F1.4 GM "&gt;35mm f/3.2 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;不禁感慨一下，魯迅養活了多少紹興人。直到現在，多少店鋪都是靠著它留下的「營養」而吸引客戶，例如「孔乙己茴香豆」等等，不一而足。&lt;/p&gt;
&lt;p&gt;不知不覺天黑了，我突然發現魯迅故里晚上竟然也開門，就故地重遊了一下，其實我更主要的是想看魯迅紀念館，上次疫情期間它晚上不開門，錯過了。&lt;/p&gt;
&lt;p&gt;在魯迅故居中，給我留下主要印象的是紹興的「祝福」儀式：&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04310.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04310.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04310.jpg" type="image/jpeg"/&gt;&lt;img title="祝福" alt="祝福" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04310.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;祝福&lt;/span&gt;&lt;span class="exif" title="35mm f/1.8 FE 35mm F1.4 GM "&gt;35mm f/1.8 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;而在魯迅紀念館中，主要感慨於魯迅原配朱安和在一起生活的許廣平的故事，以及魯迅晚期病中的狀態。當然，魯迅為治中國人心病的一路歷程每看一次都令人動容。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04313.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04313.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04313.jpg" type="image/jpeg"/&gt;&lt;img title="俯首甘為孺子牛" alt="俯首甘為孺子牛" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04313.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;俯首甘為孺子牛&lt;/span&gt;&lt;span class="exif" title="35mm f/1.8 FE 35mm F1.4 GM "&gt;35mm f/1.8 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;非常幸運，魯迅刻「早」字的課桌原件展出在紀念館中，而這件文物在過去數十年間一直沒有對外展出，都是複製件。你能在課桌上找到「早」字在哪裡嗎？我當時硬是沒有找到，後來在網上查資料後重新找，才找到了它的位置。你可以放大下面圖片仔細找找。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04315.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04315.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04315.jpg" type="image/jpeg"/&gt;&lt;img title="魯迅在三味書屋的課桌" alt="魯迅在三味書屋的課桌" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04315.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;魯迅在三味書屋的課桌&lt;/span&gt;&lt;span class="exif" title="35mm f/1.8 FE 35mm F1.4 GM "&gt;35mm f/1.8 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="倉橋直街"&gt;倉橋直街&lt;/h2&gt;
&lt;p&gt;離開魯迅故里附近，我直奔不遠處的倉橋直街。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04323.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04323.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04323.jpg" type="image/jpeg"/&gt;&lt;img title="倉橋直街路牌" alt="倉橋直街路牌" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04323.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;倉橋直街路牌&lt;/span&gt;&lt;span class="exif" title="35mm f/1.6 FE 35mm F1.4 GM "&gt;35mm f/1.6 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;如前所述，我這次旅行沒有做過多攻略，因此對倉橋直街也沒什麼太大概念。但到了之後我發現，這個街的小巷子很長，且老房子還是挺多的，走走及拍拍照，很不錯。當然，老房子裡經營的肯定都是中國古街清一色的內容——特色小吃。&lt;/p&gt;
&lt;figure-group&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04326.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04326.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04326.jpg" type="image/jpeg"/&gt;&lt;img title="古街小巷" alt="古街小巷" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04326.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;古街小巷&lt;/span&gt;&lt;span class="exif" title="35mm f/1.4 FE 35mm F1.4 GM "&gt;35mm f/1.4 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="DSC04330.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04330.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04330.jpg" type="image/jpeg"/&gt;&lt;img title="古街對聯" alt="古街對聯" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04330.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;古街對聯&lt;/span&gt;&lt;span class="exif" title="35mm f/1.4 FE 35mm F1.4 GM "&gt;35mm f/1.4 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/figure-group&gt;&lt;/p&gt;
&lt;p&gt;可以看出紹興政府為了提振旅遊做了不少努力。比如在倉橋直街的十字路口，發現其交叉的街道掛滿了燈籠，估計是想營造打卡點，但其實在這裡拍照有點危險，車不少：&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04334.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04334.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04334.jpg" type="image/jpeg"/&gt;&lt;img title="樹上燈籠" alt="樹上燈籠" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04334.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;樹上燈籠&lt;/span&gt;&lt;span class="exif" title="35mm f/1.4 FE 35mm F1.4 GM "&gt;35mm f/1.4 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;徹底離開倉橋直街，回去取我車的路上，突然無意間看到了秋瑾的紀念塑像。在夜光下這樣的場景具有獨特的視覺效果，配合孫中山的題詞「巾幗英雄」，顯得格外聖潔和印象深刻，大量敬贈的鮮花擺放在路邊，這種不期而遇的震撼讓我有點懵。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04349.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04349.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04349.jpg" type="image/jpeg"/&gt;&lt;img title="秋瑾紀念塑像及鮮花" alt="秋瑾紀念塑像及鮮花" src="https://ceeji.net/blog/travel-2024-04-shaoxing-2/DSC04349.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;秋瑾紀念塑像及鮮花&lt;/span&gt;&lt;span class="exif" title="35mm f/2.8 FE 35mm F1.4 GM "&gt;35mm f/2.8 FE 35mm F1.4 GM&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>國內 AI 應用創業為何舉步維艱？國內 AI 創業者的出路何在？</title><link>https://ceeji.net/zh-hant/blog/ai-app-creator-china-vs-west/</link><pubDate>Thu, 25 Apr 2024 19:05:40 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/ai-app-creator-china-vs-west/</guid><description>&lt;p&gt;不知道大家有沒有發現，在當前 AI 技術蓬勃發展的浪潮中，海外湧現出眾多獨立開發者憑藉創新應用斬獲成功，而反觀國內，AI 創業之路卻步履蹣跚。&lt;/p&gt;
&lt;p&gt;即使拋開AI，這個現象其實已經持續了幾年了，而且愈演愈烈。做網際網路產品，國內網際網路的這一現象背後，凸顯出國內網際網路生態中流量分配的失衡，以及平臺政策對獨立開發者的壁壘。&lt;/p&gt;
&lt;p&gt;首先，國內網際網路流量高度集中於移動端的頭部應用。據統計，微信和抖音兩大平臺佔據了絕大部分的使用者使用時長。這意味著，對於初創團隊而言，要在短時間內獲取可觀的使用者規模，只能依附於既有平臺，而平臺往往對第三方應用抱有排他性。微信對小程式訪問連結的限制，以及抖音對外鏈跳轉的封禁，無不凸顯出平臺對流量的壟斷和控制。&lt;/p&gt;
&lt;p&gt;因此，創業者們無法引導使用者走出平臺，獨立 App 的生存空間被極度壓縮。&lt;/p&gt;
&lt;p&gt;其次，頭部平臺基於自身的商業邏輯，更青睞變現效率高、有助於延長使用者時長的內容形態。這導致短影片和直播成為平臺重點扶持的方向，而創新型應用則難覓機會。不少創業者被迫轉型，從事內容生產，在擅長的技術之外耗費大量精力。平臺主導的商業生態，並未給創新軟體應用預留髮展的空間。&lt;/p&gt;
&lt;p&gt;相比之下，海外市場則呈現出不同的圖景。得益於開放而中立的社交網路，使用者可以自由地在平臺間跳轉。加之海量的 Web 端流量，使得初創團隊能夠透過搜尋引擎最佳化等手段，持續獲得忠實使用者。再者，推特、臉書等社交媒體允許外鏈的存在，使用者可以在平臺內發現新鮮應用，繼而走出圍牆花園，與開發者直接互動。這些因素共同構築起良性迴圈，催生出更多新穎獨特的 AI 應用，引領創新浪潮。&lt;/p&gt;
&lt;p&gt;那麼，國內 AI 創業者的出路何在？&lt;/p&gt;
&lt;p&gt;挺難的。&lt;/p&gt;
&lt;p&gt;從長遠來看，只有打破頭部平臺對流量的壟斷格局，創新的土壤才能培育而生。倘若 App 端主導地位動搖， Web 端的復興將為創業者帶來新的想象空間。&lt;/p&gt;
&lt;p&gt;綜上所述，國內 AI 創業之困，根源在於頭部平臺對流量的壟斷割裂。&lt;/p&gt;
&lt;p&gt;短期內，出海或許是最理想的選擇，藉助海外開放而活躍的網際網路生態，讓創意落地生根。&lt;/p&gt;
&lt;p&gt;而從國內市場來看，要麼順應平臺“遊戲規則”發力內容領域，要麼立足細分賽道開拓創新路徑。無論何種選擇，創業者們都需要保持敏銳洞察，隨時調整策略。在 AI 革命的浪潮中，唯有直面挑戰、把握機遇，才能成就非凡。&lt;/p&gt;</description></item><item><title>為了造車，拋妻棄子？還有多少老婆孩子要被犧牲？</title><link>https://ceeji.net/zh-hant/blog/no-wife-for-making-cars/</link><pubDate>Tue, 23 Apr 2024 19:18:04 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/no-wife-for-making-cars/</guid><description>&lt;p&gt;希望以後我們國產汽車的發佈會，不要一個個像內捲到內傷的孩子在訴苦。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;a href="2024-04-23-19-22-52.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/no-wife-for-making-cars/2024-04-23-19-22-52.png"/&gt;&lt;img title="" alt="" src="https://ceeji.net/blog/no-wife-for-making-cars/2024-04-23-19-22-52.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="1"&gt;1&lt;/h2&gt;
&lt;p&gt;我無意間看到了智己L6發佈會上聯席CEO劉濤的這麼一段話：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們的同學甚至連自己小孩子的出生都會錯過&lt;/p&gt;
&lt;p&gt;我們有同學一狠心&lt;/p&gt;
&lt;p&gt;把自己年幼的孩子送去了寄宿制學校……&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我們國人什麼時候才能不被這種話語所感動？&lt;/p&gt;
&lt;p&gt;令人欣慰的是，這話一出，網上並非一片感動，而是炸了鍋。有人調侃道：「少買一輛智己，就少一個寄宿的孩子。」&lt;/p&gt;
&lt;p&gt;有的甚至給L6貼上了「拋妻棄子車」的標籤。&lt;/p&gt;
&lt;p&gt;這位高管的苦衷，或許只有他自己心裡清楚。但是，這不禁讓人思考：在汽車行業裡，這樣的家庭犧牲是不是成了常態？&lt;/p&gt;
&lt;p&gt;其實，智己並非個例。有些車企不僅將週六定為正常工作日，還讓員工「悄悄」規避法律風險。這種情況在業內已經不是秘密。&lt;/p&gt;
&lt;p&gt;犧牲了個人和家庭生活，真的能造出好車，銷量就能飆升嗎？&lt;/p&gt;
&lt;h2 id="2"&gt;2&lt;/h2&gt;
&lt;p&gt;汽車行業的高速發展，似乎讓一些企業忘了，造車不僅僅是生產線上的機械運轉，更是人的智慧和生活體驗的結晶。&lt;/p&gt;
&lt;p&gt;在汽車行業的無情競賽中，有一課似乎被遺忘了：亨利·福特的智慧。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;a href="2024-04-23-19-22-22.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/no-wife-for-making-cars/2024-04-23-19-22-22.png"/&gt;&lt;img title="" alt="" src="https://ceeji.net/blog/no-wife-for-making-cars/2024-04-23-19-22-22.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;1914年，福特汽車公司推出T型車後，福特宣佈了一個震驚世界的決策：工人的日薪將達到5美元。這一創舉不僅僅是對社會公平的貢獻，更是一條精明的商業法則。福特深知，只有當工資高且穩定時，工人才能成為消費者，市場才會穩定增長，他們才買得起T型車。&lt;/p&gt;
&lt;p&gt;福特的這一理念開啟了一個良性迴圈：待遇優厚的工人帶來了消費需求，進而促進了業務擴張和就業增加。他是最早明確提出這個概念的商業領袖之一。&lt;/p&gt;
&lt;p&gt;福特的智慧並非孤例，其他高管和強大的工會組織也採納了這一理念，通用汽車和全美汽車工人聯合會簽訂的《底特律條約》便是最好的證明。這種「利益共享資本主義」的理念，曾帶領美國經歷了二戰後的經濟黃金時期，創造了前所未有的中產階級繁榮景象。那時的商界領袖們深信，企業的成功與工人福利成正比。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;a href="2024-04-23-19-22-41.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/no-wife-for-making-cars/2024-04-23-19-22-41.png"/&gt;&lt;img title="" alt="" src="https://ceeji.net/blog/no-wife-for-making-cars/2024-04-23-19-22-41.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;像標準石油公司的弗蘭克·W·艾布拉姆和通用電氣的厄爾·S·威利斯等人，都提倡平衡各方利益，認為員工的經濟安全是企業最寶貴的資產。&lt;/p&gt;
&lt;p&gt;然而，自20世紀70年代晚期以來，這一理念似乎逐漸被邊緣化。生產力雖然大幅提升，但工人的實際工資和福利卻幾乎停滯不前。公司利潤飆升，而中產階級的收入卻停滯，我們正在為這種轉變付出代價。福特曾預言，如果普通民眾沒有穩定的收入增長，經濟將會停滯不前。&lt;/p&gt;
&lt;p&gt;現在，我們似乎正遭受著這一預言的驗證。就像福特說的那樣，如果普通民眾沒有收入穩步增長的穩定工作，經濟就會停滯不前。自20世紀90年代初以來，世界已經多次陷入「失業型復甦」的泥沼。&lt;/p&gt;
&lt;p&gt;我們不能忘記，在造車的過程中，不僅需要技術和創新，還需要人的智慧和生活體驗。沒有時間去享受生活的人，如何能夠理解使用者的需求，造出能觸動人心的產品？&lt;/p&gt;
&lt;p&gt;汽車行業的領袖們應該回顧歷史，重新領悟福特的智慧：只有當中產階級能從國家經濟收入中分到更多的份額，經濟才能更快增長，我們的產品也才能更加卓越。&lt;/p&gt;
&lt;p&gt;畢竟，只有幸福的員工，才能造出讓人幸福的車。&lt;/p&gt;</description></item><item><title>正確實現根據使用者偏好自動切換網頁中文簡繁版本</title><link>https://ceeji.net/zh-hant/blog/language-auto-switch-chinese/</link><pubDate>Tue, 23 Apr 2024 03:50:36 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/language-auto-switch-chinese/</guid><description>&lt;p&gt;很多人都沒有正確地實現中文簡繁體語言的自動切換，其實現有瑕疵，造成使用者體驗和 SEO 的問題。這篇文章直接給你一個終極答案，照抄就可以了。&lt;/p&gt;
&lt;p&gt;在給出具體的程式碼之前，先普及幾個知識點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;根據規範，中文的語言編碼有兩種形式，一種是根據簡繁來標識，如 &lt;code&gt;zh-hans&lt;/code&gt; 代表簡體中文，&lt;code&gt;zh-hant&lt;/code&gt; 代表繁體中文；另一種是根據地區來標識，如 &lt;code&gt;zh-cn&lt;/code&gt; 代表中國大陸地區的中文，&lt;code&gt;zh-tw&lt;/code&gt; 代表臺灣地區的中文。我們的程式碼要相容兩種形式。&lt;/li&gt;
&lt;li&gt;大多數中文網站沒必要針對臺灣、香港、新加坡等不同地域實現不同的語言切換，例如臺灣和香港我們一般共用繁體中文。因此，網站的繁體中文語言 url 字首應該使用 &lt;code&gt;zh-hant&lt;/code&gt; 而不是 &lt;code&gt;zh-TW&lt;/code&gt; 或 &lt;code&gt;zh-HK&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;為了 SEO，我們需要注意兩件事：
&lt;ul&gt;
&lt;li&gt;應該在網站的 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 標籤上新增 &lt;code&gt;lang&lt;/code&gt; 屬性，以便搜尋引擎正確識別網站的語言；&lt;/li&gt;
&lt;li&gt;對於搜尋引擎的爬蟲（蜘蛛），不要自動跳轉到其他語言版本，否則可能會導致其無法索引到各種語言的版本；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;一些使用者不知道如何在瀏覽器或作業系統中設定自己偏好的語言，因此使用者會在網頁上手工切換到自己偏好的語言。我們需要記住使用者選擇的語言，避免重複跳轉到作業系統或瀏覽器設定的語言。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面是我們的終極程式碼。&lt;/p&gt;
&lt;p&gt;在你網頁的 &lt;code&gt;JavaScript&lt;/code&gt; 指令碼中，新增如下程式碼：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;beforeSwitchLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;preferred_lang&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;beforeSwitchLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;beforeSwitchLanguage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;autoSwitchLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 是否為搜尋引擎蜘蛛
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isBot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/(Googlebot\/|Googlebot-Mobile|Googlebot-Image|Googlebot-News|Googlebot-Video|AdsBot-Google([^-]|$)|AdsBot-Google-Mobile|Feedfetcher-Google|Mediapartners-Google|Mediapartners \(Googlebot\)|APIs-Google|Google-InspectionTool|Storebot-Google|GoogleOther|bingbot|Slurp|[wW]get|LinkedInBot|Python-urllib|python-requests|aiohttp|httpx|libwww-perl|httpunit|Nutch|Go-http-client|phpcrawl|msnbot|jyxobot|FAST-WebCrawler|FAST Enterprise Crawler|BIGLOTRON|Teoma|convera|seekbot|Gigabot|Gigablast|exabot|ia_archiver|GingerCrawler|webmon |HTTrack|grub\.org|UsineNouvelleCrawler|antibot|netresearchserver|speedy|fluffy|findlink|msrbot|panscient|yacybot|AISearchBot|ips-agent|tagoobot|MJ12bot|woriobot|yanga|buzzbot|mlbot|yandex\.com\/bots|purebot|Linguee Bot|CyberPatrol|voilabot|Baiduspider|citeseerxbot|spbot|twengabot|postrank|Turnitin|scribdbot|page2rss|sitebot|linkdex|Adidxbot|ezooms|dotbot|Mail\.RU_Bot|discobot|heritrix|findthatfile|europarchive\.org|NerdByNature\.Bot|sistrix crawler|Ahrefs(Bot|SiteAudit)|fuelbot|CrunchBot|IndeedBot|mappydata|woobot|ZoominfoBot|PrivacyAwareBot|Multiviewbot|SWIMGBot|Grobbot|eright|Apercite|semanticbot|Aboundex|domaincrawler|wbsearchbot|summify|CCBot|edisterbot|SeznamBot|ec2linkfinder|gslfbot|aiHitBot|intelium_bot|facebookexternalhit|Yeti|RetrevoPageAnalyzer|lb-spider|Sogou|lssbot|careerbot|wotbox|wocbot|ichiro|DuckDuckBot|lssrocketcrawler|drupact|webcompanycrawler|acoonbot|openindexspider|gnam gnam spider|web-archive-net\.com\.bot|backlinkcrawler|coccoc|integromedb|content crawler spider|toplistbot|it2media-domain-crawler|ip-web-crawler\.com|siteexplorer\.info|elisabot|proximic|changedetection|arabot|WeSEE:Search|niki-bot|CrystalSemanticsBot|rogerbot|360Spider|psbot|InterfaxScanBot|CC Metadata Scaper|g00g1e\.net|GrapeshotCrawler|urlappendbot|brainobot|fr-crawler|binlar|SimpleCrawler|Twitterbot|cXensebot|smtbot|bnf\.fr_bot|A6-Indexer|ADmantX|Facebot|OrangeBot\/|memorybot|AdvBot|MegaIndex|SemanticScholarBot|ltx71|nerdybot|xovibot|BUbiNG|Qwantify|archive\.org_bot|Applebot|TweetmemeBot|crawler4j|findxbot|S[eE][mM]rushBot|yoozBot|lipperhey|Y!J|Domain Re-Animator Bot|AddThis|Screaming Frog SEO Spider|MetaURI|Scrapy|Livelap[bB]ot|OpenHoseBot|CapsuleChecker|collection@infegy\.com|IstellaBot|DeuSu\/|betaBot|Cliqzbot\/|MojeekBot\/|netEstate NE Crawler|SafeSearch microdata crawler|Gluten Free Crawler\/|Sonic|Sysomos|Trove|deadlinkchecker|Slack-ImgProxy|Embedly|RankActiveLinkBot|iskanie|SafeDNSBot|SkypeUriPreview|Veoozbot|Slackbot|redditbot|datagnionbot|Google-Adwords-Instant|adbeat_bot|WhatsApp|contxbot|pinterest\.com\/bot|electricmonk|GarlikCrawler|BingPreview\/|vebidoobot|FemtosearchBot|Yahoo Link Preview|MetaJobBot|DomainStatsBot|mindUpBot|Daum\/|Jugendschutzprogramm-Crawler|Xenu Link Sleuth|Pcore-HTTP|moatbot|KosmioBot|[pP]ingdom|AppInsights|PhantomJS|Gowikibot|PiplBot|Discordbot|TelegramBot|Jetslide|newsharecounts|James BOT|Bark[rR]owler|TinEye|SocialRankIOBot|trendictionbot|Ocarinabot|epicbot|Primalbot|DuckDuckGo-Favicons-Bot|GnowitNewsbot|Leikibot|LinkArchiver|YaK\/|PaperLiBot|Digg Deeper|dcrawl|Snacktory|AndersPinkBot|Fyrebot|EveryoneSocialBot|Mediatoolkitbot|Luminator-robots|ExtLinksBot|SurveyBot|NING\/|okhttp|Nuzzel|omgili|PocketParser|YisouSpider|um-LN|ToutiaoSpider|MuckRack|Jamie&amp;#39;s Spider|AHC\/|NetcraftSurveyAgent|Laserlikebot|^Apache-HttpClient|AppEngine-Google|Jetty|Upflow|Thinklab|Traackr\.com|Twurly|Mastodon|http_get|DnyzBot|botify|007ac9 Crawler|BehloolBot|BrandVerity|check_http|BDCbot|ZumBot|EZID|ICC-Crawler|ArchiveBot|^LCC |filterdb\.iss\.net\/crawler|BLP_bbot|BomboraBot|Buck\/|Companybook-Crawler|Genieo|magpie-crawler|MeltwaterNews|Moreover|newspaper\/|ScoutJet|(^| )sentry\/|StorygizeBot|UptimeRobot|OutclicksBot|seoscanners|Hatena|Google Web Preview|MauiBot|AlphaBot|SBL-BOT|IAS crawler|adscanner|Netvibes|acapbot|Baidu-YunGuanCe|bitlybot|blogmuraBot|Bot\.AraTurka\.com|bot-pge\.chlooe\.com|BoxcarBot|BTWebClient|ContextAd Bot|Digincore bot|Disqus|Feedly|Fetch\/|Fever|Flamingo_SearchEngine|FlipboardProxy|g2reader-bot|G2 Web Services|imrbot|K7MLWCBot|Kemvibot|Landau-Media-Spider|linkapediabot|vkShare|Siteimprove\.com|BLEXBot\/|DareBoost|ZuperlistBot\/|Miniflux\/|Feedspot|Diffbot\/|SEOkicks|tracemyfile|Nimbostratus-Bot|zgrab|PR-CY\.RU|AdsTxtCrawler|Datafeedwatch|Zabbix|TangibleeBot|google-xrawler|axios|Amazon CloudFront|Pulsepoint|CloudFlare-AlwaysOnline|Google-Structured-Data-Testing-Tool|WordupInfoSearch|WebDataStats|HttpUrlConnection|Seekport Crawler|ZoomBot|VelenPublicWebCrawler|MoodleBot|jpg-newsbot|outbrain|W3C_Validator|Validator\.nu|W3C-checklink|W3C-mobileOK|W3C_I18n-Checker|FeedValidator|W3C_CSS_Validator|W3C_Unicorn|Google-PhysicalWeb|Blackboard|ICBot\/|BazQux|Twingly|Rivva|Experibot|awesomecrawler|Dataprovider\.com|GroupHigh\/|theoldreader\.com|AnyEvent|Uptimebot\.org|Nmap Scripting Engine|2ip\.ru|Clickagy|Caliperbot|MBCrawler|online-webceo-bot|B2B Bot|AddSearchBot|Google Favicon|HubSpot|Chrome-Lighthouse|HeadlessChrome|CheckMarkNetwork\/|www\.uptime\.com|Streamline3Bot\/|serpstatbot\/|MixnodeCache\/|^curl|SimpleScraper|RSSingBot|Jooblebot|fedoraplanet|Friendica|NextCloud|Tiny Tiny RSS|RegionStuttgartBot|Bytespider|Datanyze|Google-Site-Verification|TrendsmapResolver|tweetedtimes|NTENTbot|Gwene|SimplePie|SearchAtlas|Superfeedr|feedbot|UT-Dorkbot|Amazonbot|SerendeputyBot|Eyeotabot|officestorebot|Neticle Crawler|SurdotlyBot|LinkisBot|AwarioSmartBot|AwarioRssBot|RyteBot|FreeWebMonitoring SiteChecker|AspiegelBot|NAVER Blog Rssbot|zenback bot|SentiBot|Domains Project\/|Pandalytics|VKRobot|bidswitchbot|tigerbot|NIXStatsbot|Atom Feed Robot|[Cc]urebot|PagePeeker\/|Vigil\/|rssbot\/|startmebot\/|JobboerseBot|seewithkids|NINJA bot|Cutbot|BublupBot|BrandONbot|RidderBot|Taboolabot|Dubbotbot|FindITAnswersbot|infoobot|Refindbot|BlogTraffic\/\d\.\d+ Feed-Fetcher|SeobilityBot|Cincraw|Dragonbot|VoluumDSP-content-bot|FreshRSS|BitBot|^PHP-Curl-Class|Google-Certificates-Bridge|centurybot|Viber|e\.ventures Investment Crawler|evc-batch|PetalBot|virustotal|(^| )PTST\/|minicrawler|Cookiebot|trovitBot|seostar\.co|IonCrawl|Uptime-Kuma|SeekportBot|FreshpingBot|Feedbin|CriteoBot|Snap URL Preview Service|Better Uptime Bot|RuxitSynthetic|Google-Read-Aloud|Valve\/Steam|OdklBot\/|GPTBot|ChatGPT-User|YandexRenderResourcesBot\/|LightspeedSystemsCrawler|ev-crawler\/|BitSightBot\/|woorankreview\/|Google-Safety|AwarioBot|DataForSeoBot|Linespider|WellKnownBot|A Patent Crawler|StractBot|search\.marginalia\.nu|YouBot|Nicecrawler|Neevabot|BrightEdge Crawler|SiteCheckerBotCrawler|TombaPublicWebCrawler|CrawlyProjectCrawler|KomodiaBot|KStandBot|CISPA Webcrawler|MTRobot|hyscore\.io|AlexandriaOrgBot|2ip bot|Yellowbrandprotectionbot|SEOlizer|vuhuvBot|INETDEX-BOT|Synapse|t3versionsBot|deepnoc|Cocolyzebot|hypestat|ReverseEngineeringBot|sempi\.tech|Iframely|MetaInspector|node-fetch|lkxscan|python-opengraph|OpenGraphCheck|developers\.google\.com\/\+\/web\/snippet|SenutoBot|MaCoCu|NewsBlur|inoreader|NetSystemsResearch|PageThing|WordPress\/|PhxBot|ImagesiftBot|Expanse|InternetMeasurement|^BW\/|GeedoBot|Audisto Crawler|PerplexityBot\/|[cC]laude[bB]ot)/g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userAgent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isBot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 如果使用者手工切換過語言，則記住
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;preferredLang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;preferred_lang&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;preferredLang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 查詢瀏覽器第一偏好的 &amp;#39;zh&amp;#39; 類語言
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;zh&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isPreferSC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;zh-CN&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;zh-SG&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;zh-hans&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;preferredLang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isPreferSC&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;zh-hans&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;zh-hant&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;preferredLang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 注意：此處需要根據你自己網站的情況進行改寫，以獲取到正確的跳轉 url。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 查詢 id 為 link-lang-[preferredLang] 的 a 標籤指向的連結
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;link-lang-&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;preferredLang&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 如果找到，自動跳轉
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;這裡的主要邏輯如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我們在 &lt;code&gt;beforeSwitchLanguage&lt;/code&gt; 函式中使用 &lt;code&gt;localStorage&lt;/code&gt; 來儲存使用者偏好的語言。&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;autoSwitchLanguage&lt;/code&gt; 函式中，我們首先判斷使用者是否是搜尋引擎蜘蛛，如果是，則不進行自動切換。&lt;/li&gt;
&lt;li&gt;然後我們查詢使用者瀏覽器的第一偏好的中文語言，如果找到，則自動切換到簡體或繁體中文。&lt;/li&gt;
&lt;li&gt;如果使用者手工切換過語言，則記住使用者的選擇，下次訪問時自動切換到使用者偏好的語言。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要注意的是，自動跳轉到相應語言的部分，需要你根據自己網站的情況判斷正確的跳轉 url。&lt;/p&gt;
&lt;p&gt;我自己網站實現中，網頁會有一個指向另一種中文的連結，因此我這裡使用的是查詢連結對應的 url 的方法來實現。這種實現比較適合於 Hugo 等靜態網站，一般主題中會自帶語言切換連結，因此在 &lt;code&gt;JavaScript&lt;/code&gt; 指令碼中不需要再手工生成連結，而是引用網頁上的連結，這樣也增加了可維護性。&lt;/p&gt;
&lt;p&gt;最後還要做一件事，在使用者手工切換語言的連結上呼叫 &lt;code&gt;beforeSwitchLanguage&lt;/code&gt; 方法並傳入要跳轉的語言編碼，這樣我們就記住了使用者的偏好。例如，如果你透過 &lt;code&gt;a&lt;/code&gt; 標籤進行跳轉，可以這麼寫：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;onclick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;beforeSwitchLanguage(&amp;#39;zh-hant&amp;#39;)&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;link-lang-zh-hant&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;menu-link&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;xxxxxx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;繁體中文&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也就是新增一個 &lt;code&gt;onclick&lt;/code&gt; 事件。&lt;/p&gt;</description></item><item><title>紹興之旅（1）：羊山石境與柯橋古鎮</title><link>https://ceeji.net/zh-hant/blog/travel-2024-04-shaoxing-1/</link><pubDate>Sat, 20 Apr 2024 01:25:01 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/travel-2024-04-shaoxing-1/</guid><description>&lt;p&gt;2024年4月，我決定趁著春光來一段浙東的旅行，從杭州出發，穿過紹興，沿著&lt;a href="https://baike.baidu.com/item/%E6%B5%99%E4%B8%9C%E5%94%90%E8%AF%97%E4%B9%8B%E8%B7%AF/7280668" target="_blank" rel="noopener"&gt;浙東唐詩之路&lt;/a&gt;前往嵊州、新昌、天台方向。&lt;/p&gt;
&lt;p&gt;為了方便看沿路的風景，同時也為了節約成本，我決定透過自駕的方式旅行，晚上儘量睡在車上，一路上不走高速，儘量用電而不是油。整個旅行持續了一週左右的時間，中間公司有事就回杭州，沒事就睡車裡以便第二天繼續旅行。&lt;/p&gt;
&lt;p&gt;我這次旅行的目的有兩個，一是多看看浙江的人文景色；二是遊山玩水，鍛鍊身體。在路線選擇上，我曾經在一個偶然的機會去新昌開過會，另外還去過一次十九峰，感覺那邊的景色十分不錯。&lt;/p&gt;
&lt;p&gt;這次旅行整體比較匆忙，沒有怎麼做攻略，但實際效果比我預期的要好不少。另外，這次旅行過程中頻繁下雨，也算是煙雨江南了。&lt;/p&gt;
&lt;h2 id="羊山石境"&gt;羊山石境&lt;/h2&gt;
&lt;p&gt;我是在知乎一篇討論浙東唐詩之路的文章上看到羊山石境的。但在去之前，我並不太瞭解羊山石境的實際情況。到達現場的時候正在下雨，下車之後映入眼簾的卻是杭州亞運會的攀巖運動館（紹興柯橋羊山攀巖中心），
仔細看的話會發現這個運動館旁邊還有一個山頭。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04140.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04140.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04140.jpg" type="image/jpeg"/&gt;&lt;img title="紹興柯橋羊山攀巖中心（亞運會攀巖場地）" alt="紹興柯橋羊山攀巖中心（亞運會攀巖場地）" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04140.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;紹興柯橋羊山攀巖中心（亞運會攀巖場地）&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;而真正的羊山石鏡在停車場邊上一個很小的小路盡頭。在景區入口，我瞭解了今日羊山的來歷：&lt;/p&gt;
&lt;p&gt;紹興古代屬於越國。史載，隋開皇九年，豪強高智慧在越州自稱天子，皇帝命晉王楊廣、水師總督楊素興兵討伐。為防後患，楊素採羊山石築羅城。&lt;/p&gt;
&lt;p&gt;羊山本來是一個完整的大山，但在千百年的採石過程後，只剩下斷崖殘壁，但反而形成了自己獨有的特色：佛在石中，石在水中，水在山中。&lt;/p&gt;
&lt;p&gt;蕭山與紹興這一帶的平原，屬於錢塘江沖積平原。水多山少，山少，石頭就少。然而築城，錢塘江攔壩，處處要用石頭，而且是大石頭。&lt;/p&gt;
&lt;p&gt;楊素在杭州築城，在紹興擴城，需要石頭，就到羊山開採。錢鏐呢，創業當年，攻克山陰郡，首先攻佔的就是羊山，並在此駐紮。還有林則徐，當年在錢塘江加固江堤時，需要大量石頭，採自羊山。所以，羊山活在很多大人物的奏摺中。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04143.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04143.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04143.jpg" type="image/jpeg"/&gt;&lt;img title="羊山石境介紹" alt="羊山石境介紹" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04143.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;羊山石境介紹&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;進入羊山石鏡後，看到的是一大片水，是一個面積不太大的湖，中間修有遊步道。沿著湖走，綠樹成蔭，水波盪漾，但沒有看到其他東西。&lt;/p&gt;
&lt;p&gt;因為在門口我已經知道了「佛在石中」的景觀，所以我一直沿著路走，一直走到了湖的盡頭。這裡果然別有洞天，有一個小寺廟「石佛禪寺」。此時雨越下越大。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04146.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04146.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04146.jpg" type="image/jpeg"/&gt;&lt;img title="石佛禪寺內部" alt="石佛禪寺內部" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04146.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;石佛禪寺內部&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;這個寺在外面看著其貌不揚，進入之後也只看到了一個普通寺廟的樣子。但是在它的一個殿的左側，有一個很小的門，裡面黑黑的，沒有什麼特別的標識。&lt;/p&gt;
&lt;p&gt;從這裡走進去，發現了羊山石鏡真正的核心景點——這裡有一個階梯，可以通往羊山被開採後留下的孤巖。在階梯上，我看到了文人墨客的崖刻。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04153.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04153.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04153.jpg" type="image/jpeg"/&gt;&lt;img title="石佛禪寺崖刻墨寶" alt="石佛禪寺崖刻墨寶" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04153.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;石佛禪寺崖刻墨寶&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;從題字來看，大多數石刻可能來自於清代和民國時期。回家後搜尋得知，其中的「飛躍」二字傳為南宋名將韓世忠書。&lt;/p&gt;
&lt;p&gt;繼續往前走可到一個修建於孤石中的佛殿，當時我以為已經走到頭了，但是仔細一看，在殿裡的右側有一入口，沿著這個口往外走，就到了石佛峰石窟造像，為江南四大石佛之一。我沒有拍照，但這個石佛是真的很壯觀，尤其是他的手，非常的令人震撼！&lt;/p&gt;
&lt;p&gt;從寺中出來回到羊山湖，發現在寺外湖邊還有一個佛像，好像是觀音像？&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04157.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04157.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04157.jpg" type="image/jpeg"/&gt;&lt;img title="寺外佛像" alt="寺外佛像" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04157.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;寺外佛像&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="柯橋古鎮"&gt;柯橋古鎮&lt;/h2&gt;
&lt;p&gt;柯橋古鎮並非我此次規劃中的路線，但好在距離羊山很近，地圖上一搜我就過去了。到了之後發現這個地方景色還挺不錯，雖然很商業化、且大多數為現代重修的仿古建築，但整體規劃設計在國內古鎮中我認為是上乘的。由於正在下雨，頗有江南煙雨的感覺。&lt;/p&gt;
&lt;p&gt;下面這張圖拍攝於藍調時分雨中的柯橋古鎮，是我這次旅行中拍攝的最滿意的照片之一：&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04199.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04199.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04199.jpg" type="image/jpeg"/&gt;&lt;img title="藍調時分雨中的柯橋古鎮" alt="藍調時分雨中的柯橋古鎮" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04199.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;藍調時分雨中的柯橋古鎮&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;在古鎮中走了一會兒，穿過一個小橋後，遠遠看到了一個仿古橋，在煙雨中很是漂亮，算是這次的一個小驚喜。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04172.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04172.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04172.jpg" type="image/jpeg"/&gt;&lt;img title="柯橋古鎮" alt="柯橋古鎮" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04172.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;柯橋古鎮&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;在古鎮中雨越來越大，我走的時間不太長就出來了。我發現附近全是新疆餐廳，於是我就隨便找了一家新疆菜來吃，畢竟新疆面是真的好吃。意外的是，對方還送了個小菜。&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04186.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04186.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04186.jpg" type="image/jpeg"/&gt;&lt;img title="新疆菜館的小菜" alt="新疆菜館的小菜" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04186.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;新疆菜館的小菜&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;figure&gt;
&lt;a href="DSC04188.avif" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04188.avif"type="image/avif"/&gt;&lt;source srcset="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04188.jpg" type="image/jpeg"/&gt;&lt;img title="新疆面" alt="新疆面" src="https://ceeji.net/blog/travel-2024-04-shaoxing-1/DSC04188.avif"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;新疆面&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Grub Filter Not Found 修復：系統升級後的引導修復</title><link>https://ceeji.net/zh-hant/blog/grub-filter-not-found-fix/</link><pubDate>Wed, 03 Apr 2024 17:11:07 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/grub-filter-not-found-fix/</guid><description>&lt;h2 id="症狀"&gt;症狀&lt;/h2&gt;
&lt;p&gt;如果你在伺服器啟動時遇到了提示 &lt;code&gt;Grub Filter Not Found&lt;/code&gt;
並自動進入 Grub Rescue（救援模式）的問題，本文給出了
完整的解決方案。&lt;/p&gt;
&lt;p&gt;昨天晚上我對時隔三五年沒有更新過的伺服器進行了升級，
把 &lt;code&gt;Debian 10&lt;/code&gt; 經過兩次更新升級到了 &lt;code&gt;Debian 12&lt;/code&gt;。
隨著系統更新，&lt;code&gt;PHP&lt;/code&gt; 也從 &lt;code&gt;7.4&lt;/code&gt; 升級到了 &lt;code&gt;8.2&lt;/code&gt;；
&lt;code&gt;Nginx&lt;/code&gt; 從 &lt;code&gt;1.15&lt;/code&gt; 升級到了 &lt;code&gt;1.22.1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;升級之後，系統執行一切正常，所有網站也都能正常訪問。
為了保證長期執行的穩定性（我的伺服器常年不重啟），我打算
在伺服器升級後順道重啟一次。結果這下可好，重啟後直接無法使用了。&lt;/p&gt;
&lt;p&gt;首先是 SSH 無法連線，然後透過雲伺服器的 Web 終端登入後，
發現螢幕顯示內容如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;error: symbol &amp;#39;grub_file_filters&amp;#39; not found.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Entering rescue mode...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub rescue&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="原因分析"&gt;原因分析&lt;/h2&gt;
&lt;p&gt;迅速分析和查閱了相關的資料，發現這個問題應該是在系統更新
過程中破壞了引導的 grub 配置造成的。網上大部分的資料都
需要掛載系統恢復光碟映象來執行 &lt;code&gt;grub-install&lt;/code&gt;，來完成引導
的修復。但對於雲伺服器，這是不可行的， 因為你無法插入
修復光碟映象。&lt;/p&gt;
&lt;p&gt;如果你和我一樣無法掛載系統恢復光碟映象，我提供兩個解決思路。&lt;/p&gt;
&lt;h3 id="方法一雲盤掛載在救援主機"&gt;方法一：雲盤掛載在救援主機&lt;/h3&gt;
&lt;p&gt;阿里雲、AWS 等伺服器支援掛載雲盤到其他主機。而有些雲伺服器，
例如&lt;code&gt;青雲&lt;/code&gt;，提供了救援主機功能。你可以利用這些功能把受損的
系統盤掛載在一個可以正常啟動的伺服器上，然後在這個伺服器上修復
你的引導。&lt;/p&gt;
&lt;p&gt;具體步驟如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 切換到 root 許可權&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo su
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查詢被掛載的損壞的系統盤的盼復&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fdisk -l
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 把損壞的系統盤的一些內容掛載到可以正常啟動的伺服器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 這裡假設你在 fdisk 中查詢到的系統碟符為 sdc，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 且系統掛載在其中的 sdc1：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mount /dev/sdc1 /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mount --bind /dev /mnt/dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mount --bind /dev/pts /mnt/dev/pts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mount --bind /proc /mnt/proc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mount --bind /sys /mnt/sys
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chroot /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 執行引導修復&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub-install /dev/sda
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;假如一切順利，系統會提示：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Installation finished. No error reported.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此時別忘了取消掛載：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 退出 chroot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 取消掛載&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;umount /mnt/dev/pts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;umount /mnt/dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;umount /mnt/proc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;umount /mnt/sys
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;umount /mnt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然後把雲盤重新掛載回損壞的主機，重啟該主機，應該可以進入系統。&lt;/p&gt;
&lt;h3 id="方法二手工引導系統"&gt;方法二：手工引導系統&lt;/h3&gt;
&lt;p&gt;如果你和我一樣倒黴，在執行 &lt;code&gt;grub-install&lt;/code&gt; 時不成功，或者你沒法
掛載系統盤到其他可用的主機，還有一個辦法，那就是手工透過 grub 引導
進入系統，然後在系統內修復 &lt;code&gt;grub&lt;/code&gt; 安裝。&lt;/p&gt;
&lt;p&gt;首先執行你的主機，在出現下面的提示時:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;error: symbol &lt;span class="s1"&gt;&amp;#39;grub_file_filters&amp;#39;&lt;/span&gt; not found.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Entering rescue mode...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub rescue&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;又或者你進入的是 &lt;code&gt;grub&lt;/code&gt; 命令列，而不是 &lt;code&gt;grub rescue&lt;/code&gt;，也是可以的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;小心地按照下列步驟執行命令。&lt;/p&gt;
&lt;p&gt;首先執行一個可以讓長輸出進行分頁的指令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;pager&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;不要有多餘的空格。&lt;/p&gt;
&lt;p&gt;然後列出自己的磁碟：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt; ls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;hd0&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;hd0,msdos2&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;hd0,msdos1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;怎麼出來了一個 &lt;code&gt;msdos&lt;/code&gt;？這說明你的磁碟使用的是以前的 &lt;code&gt;MS-DOS&lt;/code&gt; 分割槽模式，而不是 &lt;code&gt;GPT&lt;/code&gt; 模式。這不重要。&lt;/p&gt;
&lt;p&gt;我們的重點是找到你的啟動盤。比如我們嘗試 (hd0,1) 這個盤：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt; ls &lt;span class="o"&gt;(&lt;/span&gt;hd0,1&lt;span class="o"&gt;)&lt;/span&gt;/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lost+found/ bin/ boot/ cdrom/ dev/ etc/ home/ lib/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lib64/ media/ mnt/ opt/ proc/ root/ run/ sbin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;srv/ sys/ tmp/ usr/ var/ vmlinuz vmlinuz.old
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;initrd.img initrd.img.old
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;透過 ls 指令，你可以確認這個盤的內容以分析它是不是我們的啟動盤。
你也可以透過 cat 指令進一步確認系統的版本號：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt; cat &lt;span class="o"&gt;(&lt;/span&gt;hd0,1&lt;span class="o"&gt;)&lt;/span&gt;/etc/issue
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Ubuntu 14.04 LTS n l
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;假如你有多個系統或者多個碟符，一定不要搞錯。&lt;/p&gt;
&lt;p&gt;接下來手工引導系統（先別急著複製執行，看解釋）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 看完解釋後再執行哦&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;root&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;hd0,1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt; linux /boot/vmlinuz-3.13.0-29-generic &lt;span class="nv"&gt;root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sda1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt; initrd /boot/initrd.img-3.13.0-29-generic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grub&amp;gt; boot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;這裡的 &lt;code&gt;(hd0,1)&lt;/code&gt; 是你要修復引導的實際磁碟，要反覆核實清楚；&lt;/li&gt;
&lt;li&gt;這裡的 &lt;code&gt;/boot/vmlinuz-3.13.0-29-generic&lt;/code&gt; 只是一個例項，
你執行的時候，打出 /root/vmlinuz，然後按 Tab 鍵選出你
實際的 linux 核心版本號，不要照抄。如果有多個核心版本，一般
選最新的。&lt;/li&gt;
&lt;li&gt;這裡 &lt;code&gt;/boot/initrd.img-3.13.0-29-generic&lt;/code&gt; 同上。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;現在你應該可以進入系統了。&lt;/p&gt;
&lt;p&gt;注意，這時候別急著高興，趕緊修復 &lt;code&gt;grub&lt;/code&gt; 引導，不然下次重啟還是無法正常進入：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 更新 grub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; update-grub
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 系統可能輸出類似內容：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Generating grub configuration file ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found background: /usr/share/images/grub/Apollo_17_The_Last_Moon_Shot_Edit1.tga&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found background image: /usr/share/images/grub/Apollo_17_The_Last_Moon_Shot_Edit1.tga&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found linux image: /boot/vmlinuz-3.13.0-29-generic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found initrd image: /boot/initrd.img-3.13.0-29-generic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found linux image: /boot/vmlinuz-3.13.0-27-generic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found initrd image: /boot/initrd.img-3.13.0-27-generic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found linux image: /boot/vmlinuz-3.13.0-24-generic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found initrd image: /boot/initrd.img-3.13.0-24-generic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found memtest86+ image: /boot/memtest86+.elf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Found memtest86+ image: /boot/memtest86+.bin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 重新安裝 grub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; grub-install /dev/sda
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 可能的輸出：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Installing for i386-pc platform.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Installation finished. No error reported.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;這時候你的系統應該完全恢復了。&lt;/p&gt;
&lt;p&gt;參考資料：
&lt;a href="https://www.linuxfoundation.org/blog/blog/classic-sysadmin-how-to-rescue-a-non-booting-grub-2-on-linux" target="_blank" rel="noopener"&gt;Classic SysAdmin: How to Rescue a Non-booting GRUB 2 on Linux&lt;/a&gt;&lt;/p&gt;</description></item><item><title>自動更新阿里雲的 CDN HTTPS 證書</title><link>https://ceeji.net/zh-hant/blog/update-aliyun-cdn-cert/</link><pubDate>Mon, 01 Apr 2024 12:30:07 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/update-aliyun-cdn-cert/</guid><description>&lt;h2 id="開源地址"&gt;開源地址&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ceeji/aliyun-cdn-cert-bot" target="_blank" rel="noopener"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="使用說明"&gt;使用說明&lt;/h2&gt;
&lt;p&gt;這是一個可以自動更新你的阿里雲 CDN 證書的命令行工具。
基於 &lt;code&gt;Golang&lt;/code&gt; 開發。無需安裝繁重的 Python。
可以結合 &lt;code&gt;acme.sh&lt;/code&gt;、&lt;code&gt;let's encrypt&lt;/code&gt; 等工具，免費使用證書。&lt;/p&gt;
&lt;p&gt;通過這個方法，你不需要每隔幾個月就去手工更新你的 CDN 證書了。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clone 這個項目。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在項目所在文件夾中安裝依賴：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go mod init ceeji.net/aliyun-cdn-cert-bot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go get &lt;span class="s2"&gt;&amp;#34;github.com/denverdino/aliyungo/cdn&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;編譯 main.go 即可使用：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go build main.go
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;運行之前請設置下列環境變量：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ACCESS_KEY_ID&lt;/code&gt;、&lt;code&gt;ACCESS_KEY_SECRET&lt;/code&gt; 為阿里雲有權限的 RAM 子賬號信息；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALI_DOMAIN&lt;/code&gt; 為阿里雲 CDN 域名（非源站域名）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALI_CERT_PATH&lt;/code&gt; 為 CDN 證書文件名（注意要用 fullchain 的證書，否則可能有些客戶端會報錯）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALI_KEY_PATH&lt;/code&gt; 為 CDN 證書密鑰文件名。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;建議結合 crontab 設置定時任務，每天執行一次。&lt;/p&gt;
&lt;p&gt;對於 acme.sh 用戶，你可以直接設置相關路徑到 ~/.acme.sh/證書名稱/文件 這樣的路徑。&lt;/p&gt;</description></item><item><title>本站從 Wordpress 遷移到 Hugo</title><link>https://ceeji.net/zh-hant/blog/migrate-from-wordpress-to-hugo/</link><pubDate>Mon, 01 Apr 2024 16:38:34 +0800</pubDate><guid>https://ceeji.net/zh-hant/blog/migrate-from-wordpress-to-hugo/</guid><description>&lt;p&gt;時隔多年，本站終於進行了一次較大的更新，從 Wordpress 遷移到了 Hugo。這篇文章記錄了遷移的原因和過程。&lt;/p&gt;
&lt;h2 id="緣由"&gt;緣由&lt;/h2&gt;
&lt;p&gt;想從 Wordpress 遷移到 Hugo 已經有五六年了，但一直沒有進行。想遷移的原因非常簡單：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wordpress 越來越臃腫。尤其是最近幾年，我幾乎都不想登錄到 Wordpress 後臺，太多的插件年久失修，也不敢亂動，甚至 Wordpress 自身升級後連新建頁面都打不開了；&lt;/li&gt;
&lt;li&gt;Wordpress 對 Markdown 的支持是非原生的；雖然使用插件後看似效果不錯，但從數據源的角度來說，本質上它還是存儲為 &lt;code&gt;HTML&lt;/code&gt; 格式，這導致文章的結構化和批量處理效果一般。&lt;/li&gt;
&lt;li&gt;網站的訪問中有相當比例來源於繁體中文使用者，因此想更好的支持繁體中文的閱讀和使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="關鍵步驟"&gt;關鍵步驟&lt;/h2&gt;
&lt;h3 id="從-wordpress-備份提取-markdown"&gt;從 Wordpress 備份提取 Markdown&lt;/h3&gt;
&lt;p&gt;這是看似很簡單的步驟，因為有好幾個插件都支持相關的功能，也有一些命令行的腳本。但是，最要命的是轉換並不完美。&lt;/p&gt;
&lt;p&gt;我使用的是基於 NodeJS 的 &lt;a href="https://github.com/palaniraja/blog2md" target="_blank" rel="noopener"&gt;blog2md&lt;/a&gt; 腳本。
這個腳本的使用很簡單，只需要在 Wordpress 後臺導出備份的 &lt;code&gt;.xml&lt;/code&gt; 文件，然後執行腳本就行了。
你的計算機需要有 &lt;code&gt;Node&lt;/code&gt; 環境。
要注意的是，一定按照其 README 中的說明，添加 &lt;code&gt;paragraph-fix&lt;/code&gt; 參數，否則很多換行和段落會出現問題。例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;node index.js w your-wordpress-backup-export.xml out m paragraph-fix
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是即使你採用了上面的參數，轉換出的文章很多依然是有問題的。主要表現在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;部分段落丟失，即缺少換行；&lt;/li&gt;
&lt;li&gt;很多之前的代碼高亮的內容出現了多餘的轉義，例如 &lt;code&gt;*&lt;/code&gt; 變成了 &lt;code&gt;\*&lt;/code&gt;、&lt;code&gt;]&lt;/code&gt; 變成了 &lt;code&gt;\]&lt;/code&gt;。
我的理解是當初為了在 Wordpress 中存儲代碼高亮，相關插件本身做了轉義，但在導出數據時就很痛苦了。&lt;/li&gt;
&lt;li&gt;（更要命的）以 &lt;code&gt;&amp;lt;&lt;/code&gt; 開頭的內容丟失。可能因為和導出格式為 XML 有關，出現了語義上的衝突。這部分可能只能自己修了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如一個 C++ 程序：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可能會變成&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所以，我需要寫腳本來解決這個問題。&lt;/p&gt;
&lt;h3 id="使用腳本處理多餘的轉義"&gt;使用腳本處理多餘的轉義&lt;/h3&gt;
&lt;p&gt;下面是一個 NodeJS 腳本，用來批量將指定目錄下的 md 文件的正文部分包裹的代碼塊中的多餘轉義進行修復。
例如，它將 &lt;code&gt;\[&lt;/code&gt; 修復成 &lt;code&gt;[&lt;/code&gt;，&lt;code&gt;\_&lt;/code&gt; 修復成 &lt;code&gt;_&lt;/code&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 指定目錄路徑
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DIRECTORY_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;path/to/content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 遞歸地查找.md文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;findMarkdownFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isDirectory&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findMarkdownFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.md&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 處理.md文件中的代碼塊
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;processMarkdownFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 使用正則表達式匹配所有代碼塊
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/```[\s\S]*?```/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 替換代碼塊中的反轉義字符
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\\\[/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;[&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\\\]/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\\\*/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\\_/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\\\\/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\\&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 覆蓋原文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 主函數
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;markdownFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;findMarkdownFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DIRECTORY_PATH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filePath&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;markdownFiles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;processMarkdownFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;所有.md文件中的代碼塊已處理完畢。&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 運行主函數
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="notice warning" &gt;
&lt;p class="notice-title"&gt;
&lt;span class="icon-notice baseline"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="126 76.5 300 300"&gt;
&lt;path d="M297.431 324.397v-34.255c0-3.245-2.344-5.95-5.358-5.95h-32.146c-3.014 0-5.358 2.705-5.358 5.95v34.255c0 3.245 2.344 5.95 5.358 5.95h32.146c3.014 0 5.358-2.705 5.358-5.95Zm-.335-67.428 3.014-82.753c0-1.081-.502-2.524-1.674-3.425-1.005-.902-2.512-1.983-4.019-1.983h-36.834c-1.507 0-3.014 1.081-4.019 1.983-1.172.901-1.674 2.704-1.674 3.786l2.846 82.392c0 2.344 2.512 4.146 5.693 4.146h30.975c3.013 0 5.525-1.803 5.692-4.146Zm-2.344-168.39L423.34 342.425c3.683 7.032 3.516 15.686-.335 22.717-3.85 7.031-10.883 11.358-18.417 11.358H147.413c-7.534 0-14.566-4.327-18.417-11.358-3.85-7.031-4.018-15.685-.335-22.716L257.248 88.578C260.93 81.188 268.13 76.5 276 76.5c7.87 0 15.069 4.688 18.752 12.08Z"/&gt;
&lt;/svg&gt;
&lt;/span&gt;警告&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;請修改 &lt;code&gt;DIRECTORY_PATH&lt;/code&gt; 的值，並注意轉義。&lt;/li&gt;
&lt;li&gt;這個腳本會覆蓋原文件，請提前備份。而且，由於其做了批量替換，可能會影響代碼正常運行。需要手工檢查。&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;h3 id="移除不必要的-toc文章目錄"&gt;移除不必要的 TOC（文章目錄）&lt;/h3&gt;
&lt;p&gt;很多 Hugo 主題使用 &lt;code&gt;toc&lt;/code&gt; 這個 Front Matter 來標記是否展開文章目錄。對於老文章，
我寫了一個腳本，可以根據這個文章是否有實際的二級標題來判斷是否啟用 toc。
也就是說，如果一個文章的 Markdown 裡沒有兩個以上的二級標題，它會把：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;本站從 Wordpress 遷移到 Hugo&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="ld"&gt;2024-04-01T16:38:34+08:00&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;draft&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改為&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;本站從 Wordpress 遷移到 Hugo&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="ld"&gt;2024-04-01T16:38:34+08:00&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;draft&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;toc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;這樣渲染出的文件就不會有目錄了，並且不需要前端使用 Javascript 動態實現。&lt;/p&gt;
&lt;h3 id="自動翻譯簡體中文到繁體中文或相反"&gt;自動翻譯簡體中文到繁體中文（或相反）&lt;/h3&gt;
&lt;p&gt;因為這次升級的一個目的是更好地支持簡繁兩種漢字的使用者，因此我使用了一個腳本，
它可以將所有 Markdown 自動進行簡繁轉換。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Hugo&lt;/code&gt; 支持兩種多語言模式，我使用的是文件模式，也就是簡體、繁體的文章放在一起，
繁體文章增加 &lt;code&gt;.zh-hant&lt;/code&gt; 後綴名。&lt;/p&gt;
&lt;p&gt;簡繁轉換不能簡單的字字對應，因為存在很多「一對多」的問題和各地習慣用語的問題。
&lt;code&gt;Opencc&lt;/code&gt; 是一個不錯的開源工具，可以幫我們實現以詞彙為單位的簡繁轉換，提高轉換的準確率。
根據統計，本站大部分繁體用戶來自臺灣，因此我在簡體轉換繁體時，使用了臺灣的慣用詞。&lt;/p&gt;
&lt;p&gt;下面的腳本使用 &lt;code&gt;opencc&lt;/code&gt; 的 &lt;code&gt;NodeJS&lt;/code&gt; 版本進行簡繁轉換。&lt;/p&gt;
&lt;p&gt;這個腳本會把轉換後的結果放在 &lt;code&gt;DIRECTORY_OUTPATH&lt;/code&gt; 目錄下，文件名增加 &lt;code&gt;.zh-hant&lt;/code&gt; 後綴。
它只轉換文章的標題和正文，不會轉換文章的元數據，例如 &lt;code&gt;tag&lt;/code&gt; 和 &lt;code&gt;url&lt;/code&gt;，因此比較安全。&lt;/p&gt;
&lt;p&gt;使用前，你需要根據自己的情況對腳本進行適當的修改，並且需要安裝 &lt;code&gt;opencc&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm i opencc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;你需要提前修改腳本中的 &lt;code&gt;DIRECTORY_PATH&lt;/code&gt; 和 &lt;code&gt;DIRECTORY_OUTPATH&lt;/code&gt;。
如果你使用 &lt;code&gt;posts/xxx/index.md&lt;/code&gt;、&lt;code&gt;posts/xxx/index.zh-hant.md&lt;/code&gt; 這種形式，
你可以將兩個目錄設置相同。&lt;/p&gt;
&lt;p&gt;腳本內容如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;fs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OpenCC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;opencc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;converter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;OpenCC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;s2twp.json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;matter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gray-matter&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 指定目錄路徑
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DIRECTORY_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;path/to/blog/content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DIRECTORY_OUTPATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;path/to/blog/content-hant&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 遞歸地查找.md文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;findMarkdownFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isDirectory&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;findMarkdownFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;.md&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;filesToProcess&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 處理.md文件中的代碼塊
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;processMarkdownFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;zh-tw&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 解析Markdown文件的front matter
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;matter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;utf8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 翻譯正文
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;convertPromise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 翻譯標題
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;convertPromise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 構造輸出文件路徑
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outFilePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DIRECTORY_OUTPATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;.md&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;.zh-hant.md&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outFilePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 如果文件存在則不覆蓋
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;existsSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outFilePath&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newMarkdownContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;matter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newMarkdownContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 主函數
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;markdownFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;findMarkdownFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DIRECTORY_PATH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filePath&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;markdownFiles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;processMarkdownFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;所有.md文件已處理完畢。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 運行主函數
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="notice warning" &gt;
&lt;p class="notice-title"&gt;
&lt;span class="icon-notice baseline"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="126 76.5 300 300"&gt;
&lt;path d="M297.431 324.397v-34.255c0-3.245-2.344-5.95-5.358-5.95h-32.146c-3.014 0-5.358 2.705-5.358 5.95v34.255c0 3.245 2.344 5.95 5.358 5.95h32.146c3.014 0 5.358-2.705 5.358-5.95Zm-.335-67.428 3.014-82.753c0-1.081-.502-2.524-1.674-3.425-1.005-.902-2.512-1.983-4.019-1.983h-36.834c-1.507 0-3.014 1.081-4.019 1.983-1.172.901-1.674 2.704-1.674 3.786l2.846 82.392c0 2.344 2.512 4.146 5.693 4.146h30.975c3.013 0 5.525-1.803 5.692-4.146Zm-2.344-168.39L423.34 342.425c3.683 7.032 3.516 15.686-.335 22.717-3.85 7.031-10.883 11.358-18.417 11.358H147.413c-7.534 0-14.566-4.327-18.417-11.358-3.85-7.031-4.018-15.685-.335-22.716L257.248 88.578C260.93 81.188 268.13 76.5 276 76.5c7.87 0 15.069 4.688 18.752 12.08Z"/&gt;
&lt;/svg&gt;
&lt;/span&gt;警告&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;不要使用 &lt;code&gt;zh-tw&lt;/code&gt;、&lt;code&gt;zh-hk&lt;/code&gt;、&lt;code&gt;zh-cn&lt;/code&gt; 等作為語言標識。因為他們代表的是地區。作為一個小站點，你估計不太可能會為香港、臺灣、新加坡各做一個不同的站點。&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;zh-hant&lt;/code&gt; 代表傳統漢字，&lt;code&gt;zh-hans&lt;/code&gt; 代表簡體中文是明顯更加通用的選擇。這也方便瀏覽器、搜索引擎判斷你的目標用戶。比如，你使用了 &lt;code&gt;zh-hant&lt;/code&gt;，香港訪問者不會被排除在外。&lt;/li&gt;
&lt;li&gt;你可以訪問 &lt;code&gt;opencc&lt;/code&gt; 的 gihhub 頁面，查找不同的配置文件。不同的配置文件會使用不同的慣用詞，請根據你實際的需求進行修改。我使用的是 &lt;code&gt;s2tw.json&lt;/code&gt; 文件，代表使用臺灣慣用詞進行簡體到繁體的轉換。&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;p&gt;你也可以通過修改 &lt;code&gt;s2twp.json&lt;/code&gt; 配置文件的名字實現繁體-&amp;gt;簡體的轉換。&lt;/p&gt;
&lt;h3 id="手工檢查所有文章"&gt;手工檢查所有文章&lt;/h3&gt;
&lt;p&gt;雖然做了自動化處理，但很多文章依然有問題，需要手工檢查一遍。&lt;/p&gt;
&lt;h3 id="選擇合適的評論系統"&gt;選擇合適的評論系統&lt;/h3&gt;
&lt;p&gt;我選擇的是 &lt;code&gt;Waline&lt;/code&gt;，但你可以選擇任何你喜歡的評論系統。唯一的建議是，
評論數據需要掌握在自己手裡，因此必須選擇可以備份評論數據的評論系統。
否則，一旦你的託管方式發生變化，你可能會追悔莫及。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Waline&lt;/code&gt; 支持多種數據源，我選擇的是 &lt;code&gt;sqlite&lt;/code&gt;，因為我有
自己的服務器，並且我希望一個節約內存的輕量化解決方案。&lt;/p&gt;
&lt;h3 id="從-wordpress-評論遷移到-waline"&gt;從 Wordpress 評論遷移到 Waline&lt;/h3&gt;
&lt;p&gt;目前網絡上似乎還沒有從 Wordpress 評論遷移到 Waline 的現成方案。
本文提供了一種方案，可以將 Wordpress 所有評論無損地遷移到 Waline。&lt;/p&gt;
&lt;p&gt;首先從 Wordpress 後臺，導出所有內容的 xml 文件。&lt;/p&gt;
&lt;p&gt;然後執行我寫的腳本（你需要有 NodeJS），對 xml 文件進行分析，生成可以導入
到 Waline 的導入格式（注意修改 &lt;code&gt;WORDPRESS_XML_FILE&lt;/code&gt; 變量）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xml2js&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;xml2js&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;xml2js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Parser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// WordPress備份文件的路徑
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WORDPRESS_XML_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;WordPress.2024-03-28.xml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 讀取XML文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WORDPRESS_XML_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Error reading XML file:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 解析XML數據
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Error parsing XML data:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 初始化評論數組
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;commentsArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 遍歷每個item（文章或頁面）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 判斷是否有評論
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 遍歷每條評論
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_approved&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_type&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;pingback&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;commentObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;insertedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_author_IP&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_author_IP&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_author_url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_author_url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_author_email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_author_email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;nick&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_author&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_author&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;rid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_parent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_parent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;0&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_parent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sticky&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;approved&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;like&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;ua&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_agent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_agent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://ceeji.net&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;updatedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;objectId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wp:comment_id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;commentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;commentObj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;跳過沒批准的評論&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 將評論數組轉換為JSON並保存到文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;commentsArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;comments.json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsonContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Error writing JSON file:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Comments have been exported to comments.json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最後，在 Waline 的管理後臺，選擇導入導出功能：&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;a href="2024-04-01-17-18-10.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/migrate-from-wordpress-to-hugo/2024-04-01-17-18-10.png"/&gt;&lt;img title="" alt="" src="https://ceeji.net/blog/migrate-from-wordpress-to-hugo/2024-04-01-17-18-10.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;先選擇導出，打開導出後的 JSON 文件，格式類似如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1.31.13&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;waline&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1711963109933&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tables&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Comment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Counter&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Users&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;data&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Comment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;// 替換此處的數據
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;把 Comment 處的內容替換為腳本生成的內容，即可進行導入。注意，導入會丟失所有現有數據，
如原來有數據的，需要手工合併或提前備份。&lt;/p&gt;
&lt;h3 id="實現代碼高亮的黑暗模式自適應"&gt;實現代碼高亮的黑暗模式自適應&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Hugo&lt;/code&gt; 自帶的代碼高亮功能，一般只能設置一個樣式。如果你的主題支持自適應黑暗模式，可能會導致
在切換黑暗模式開關的時候，代碼高亮不能跟著切換。&lt;/p&gt;
&lt;p&gt;最新版本的 Hugo 使用 &lt;code&gt;chroma&lt;/code&gt; 進行語法高亮。
首先，確定你想要使用的樣式。比如我們在亮色模式下使用 &lt;code&gt;monokailight&lt;/code&gt; 樣式，在暗色模式下使用 &lt;code&gt;onedark&lt;/code&gt; 樣式。&lt;/p&gt;
&lt;p&gt;接下來，創建對應的 &lt;code&gt;.css&lt;/code&gt; 文件供 Hugo 使用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo gen chromastyles --style&lt;span class="o"&gt;=&lt;/span&gt;monokailight &amp;gt; syntax_light.css
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo gen chromastyles --style&lt;span class="o"&gt;=&lt;/span&gt;onedark &amp;gt; syntax_dark.css
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;將這兩個文件移動到你的主題 &lt;code&gt;assets&lt;/code&gt; 文件夾中（例如 &lt;code&gt;./themes/paper/assets/&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;接下來，確保我們的 Hugo 主題加載這些樣式。
為此，編輯 &lt;code&gt;./themes/paper/layout/partials/head.html&lt;/code&gt;（或者負責在你的主題中添加頭部部分的文件），添加以下內容：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{{ $syntax_dark_css := resources.Get &amp;#34;syntax_dark.css&amp;#34; | minify }}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{{ $syntax_light_css := resources.Get &amp;#34;syntax_light.css&amp;#34; | minify }}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;preload stylesheet&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;style&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ $syntax_dark_css.Permalink }}&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;preload stylesheet&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;style&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ $syntax_light_css.Permalink }}&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;這將在使用 Hugo 構建站點時使 &lt;code&gt;.css&lt;/code&gt; 文件可用，並允許頁面加載它們。&lt;/p&gt;
&lt;p&gt;順序很重要：默認情況下，應用最後引用的文件中的樣式，因為它會覆蓋之前的樣式！
為了讓 Hugo 使用我們的 &lt;code&gt;.css&lt;/code&gt; 文件作為 &lt;code&gt;chroma&lt;/code&gt; 樣式，我們需要在 Hugo 的 &lt;code&gt;hugo.toml&lt;/code&gt; 文件中明確指定以下內容：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;markup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;noClasses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;確保一切正常後，檢查你的代碼是否已使用設置的樣式進行高亮顯示。當你切換到暗色模式時，目前應該還不會有任何變化。&lt;/p&gt;
&lt;p&gt;然後你需要寫動態切換應用於代碼片段的 &lt;code&gt;.css&lt;/code&gt; 文件的腳本。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;./themes/papers/partials/header.html&lt;/code&gt;（或者負責在你的 Hugo 主題中切換模式的文件）中，找到切換模式的代碼。
每個主題都不一樣，你需要自己去找。&lt;/p&gt;
&lt;p&gt;例如它可能類似這樣：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setDark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;metaTheme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isDark&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#000&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lightBg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;htmlClass&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isDark&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;add&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;remove&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dark&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dark&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isDark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我們在這個函數調用中添加一個方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setDark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;metaTheme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isDark&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#000&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lightBg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;htmlClass&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isDark&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;add&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;remove&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dark&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dark&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isDark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;setSyntaxDark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 添加的方法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;定義 &lt;code&gt;setSyntaxDark&lt;/code&gt; 函數和一個額外的輔助函數：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getStyleSheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;styleSheets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;styleSheets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setSyntaxDark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sheet_light&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getStyleSheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;syntax_light&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sheet_dark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getStyleSheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;syntax_dark&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sheet_light&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isDark&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sheet_dark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isDark&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;隨後，使用 Hugo 重新構建你的網站，確保一切正常。&lt;/p&gt;
&lt;h3 id="簡繁中文使用相同的評論數據並自動翻譯"&gt;簡繁中文使用相同的評論數據，並自動翻譯&lt;/h3&gt;
&lt;p&gt;簡繁語言本就沒什麼大差距，不需要分開不同的評論。在 Waline 中，
你可以通過移除 url 中的語言部分使得不同語言版本共享同一個評論。&lt;/p&gt;
&lt;p&gt;修改你的 &lt;code&gt;waline&lt;/code&gt; 初始化代碼：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;#xxx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;serverURL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{{ .Page.Lang }}&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// 注意這一行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;dark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;html.dark&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 可實現黑暗模式自適應
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// path 中使用正則移除簡繁部分的網址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/zh-(hans|hant)\//&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同時我們需要定義一個 &lt;code&gt;locale&lt;/code&gt; 變量實現 &lt;code&gt;waline&lt;/code&gt; 的本地化，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;zh-hans&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;nick&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;暱称&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;nickError&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;暱称不能少于3个字符&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;邮箱&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mailError&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;请填写正确的邮件地址&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;网址&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;可选&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;欢迎评论&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sofa&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;来发评论吧~&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;提交&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;like&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;喜欢&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;cancelLike&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;取消喜欢&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;回复&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;cancelReply&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;取消回复&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;评论&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;refresh&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;刷新&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;more&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;加载更多...&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;preview&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;预览&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;emoji&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;表情&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;uploadImage&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;上传图片&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;秒前&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;分钟前&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;小时前&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;天前&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;刚刚&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;uploading&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;正在上传&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;登录&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;退出&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;博主&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sticky&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;置顶&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;字&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;wordHint&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;评论字数应在 $0 到 $1 字之间！\n当前字数：$2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;anonymous&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;匿名&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;潜水&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;冒泡&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;吐槽&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;活跃&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level4&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;话痨&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;传说&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gif&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;表情包&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gifSearchPlaceholder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;搜索表情包&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;个人资料&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;approved&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;通过&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;waiting&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;待审核&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;spam&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;垃圾&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;unsticky&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;取消置顶&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;oldest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;按倒序&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;按正序&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;hottest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;按热度&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;reactionTitle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;你认为这篇文章怎幺样？&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;zh-hant&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;nick&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;暱稱&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;nickError&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;暱稱不能少於3個字元&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;郵箱&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mailError&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;請填寫正確的郵件地址&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;網址&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;可選&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;歡迎評論&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sofa&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;來發評論吧~&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;提交&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;like&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;喜歡&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;cancelLike&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;取消喜歡&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;回覆&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;cancelReply&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;取消回覆&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;評論&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;refresh&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;重新整理&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;more&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;載入更多...&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;preview&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;預覽&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;emoji&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;表情&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;uploadImage&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;上傳圖片&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;秒前&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;分鐘前&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;小時前&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;天前&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;剛剛&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;uploading&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;正在上傳&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;登入&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;退出&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;博主&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sticky&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;置頂&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;字&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;wordHint&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;評論字數應在 $0 到 $1 字之間！\n當前字數：$2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;anonymous&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;匿名&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;潛水&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;冒泡&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;吐槽&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;活躍&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level4&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;話癆&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;level5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;傳說&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gif&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;表情包&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gifSearchPlaceholder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;搜尋表情包&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;個人資料&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;approved&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;透過&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;waiting&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;待稽核&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;spam&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;垃圾&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;unsticky&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;取消置頂&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;oldest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;按倒序&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;按正序&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;hottest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;按熱度&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;reactionTitle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;你認為這篇文章怎麼樣？&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="重定向-feedrssatom訂閱地址"&gt;重定向 Feed（Rss/Atom）訂閱地址&lt;/h3&gt;
&lt;p&gt;我的網站雖然是個小站，但依然有些人在訂閱。為了避免他們走丟，
我需要能夠保持原有的 Feed 訂閱地址。如果你使用的 OSS 或其他
無服務器（Serverless）的方式進行託管，你可能需要在你的 CDN
頁面使用 rewrite 來實現。&lt;/p&gt;
&lt;p&gt;因為我是有服務器的，我使用 &lt;code&gt;nginx&lt;/code&gt; 來實現了這一點。&lt;/p&gt;
&lt;p&gt;Hugo 默認將 RSS/Atom 發佈在根目錄下的 &lt;code&gt;index.xml&lt;/code&gt; 或類似的文件中。
找到這個文件的地址，然後你可以進行重定向：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;location ~ ^/blog/feed/?$ {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rewrite ^ /index.xml last;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面的這段 &lt;code&gt;nginx&lt;/code&gt; 配置可以把 /blog/feed 和 /blog/feed/ 指向 &lt;code&gt;index.xml&lt;/code&gt;，
同時保持對外訪問地址不變。&lt;/p&gt;
&lt;div class="notice tip" &gt;
&lt;p class="notice-title"&gt;
&lt;span class="icon-notice baseline"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="300.5 134 300 300"&gt;
&lt;path d="M551.281 252.36c0-3.32-1.172-6.641-3.515-8.985l-17.774-17.578c-2.344-2.344-5.469-3.711-8.789-3.711-3.32 0-6.445 1.367-8.789 3.71l-79.687 79.493-44.141-44.14c-2.344-2.344-5.469-3.712-8.79-3.712-3.32 0-6.444 1.368-8.788 3.711l-17.774 17.579c-2.343 2.343-3.515 5.664-3.515 8.984 0 3.32 1.172 6.445 3.515 8.789l70.704 70.703c2.343 2.344 5.664 3.711 8.789 3.711 3.32 0 6.64-1.367 8.984-3.71l106.055-106.056c2.343-2.343 3.515-5.468 3.515-8.789ZM600.5 284c0 82.813-67.188 150-150 150-82.813 0-150-67.188-150-150 0-82.813 67.188-150 150-150 82.813 0 150 67.188 150 150Z"/&gt;
&lt;/svg&gt;
&lt;/span&gt;提示&lt;/p&gt;&lt;p&gt;一個小技巧：在你的 &lt;code&gt;nginx&lt;/code&gt; 訪問日誌中搜索 feed，你可能可以看到有多少人訂閱了你的網站。&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;除了解決 Feed 網址問題外，如果你和我一樣通過 nginx 部署，建議你還要做兩件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;遷移早期定期訪問 access log，查看是否有舊網址出現了 404 錯誤，這不利於 SEO；&lt;/li&gt;
&lt;li&gt;在 nginx 配置文件裡，設置正確的 404 頁面。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="圖片管理"&gt;圖片管理&lt;/h3&gt;
&lt;p&gt;強力建議你採用下列的文件結構來存放圖片：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;posts /
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; article /
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; index.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 1.jpg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;這種方式管理方便，而且在 Markdown 編輯器中不會出現圖片看不到的問題。&lt;/p&gt;
&lt;p&gt;然後，你可以通過 &lt;code&gt;render-image&lt;/code&gt; hook 實現圖片的 CDN 化，提升全球訪問速度。
具體可進行相關搜索。&lt;/p&gt;</description></item><item><title>智繪童話</title><link>https://ceeji.net/zh-hant/blog/%E6%99%BA%E7%BB%98%E7%AB%A5%E8%AF%9D/</link><pubDate>Sun, 24 Mar 2024 18:03:50 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/%E6%99%BA%E7%BB%98%E7%AB%A5%E8%AF%9D/</guid><description>&lt;p&gt;親愛的大朋友們和小朋友們，&lt;br&gt;
就在今天，《智繪童話》小程序正式開始公測了！這是我們對於未來教育和家庭親子活動的一次大膽想象和實踐。&lt;/p&gt;
&lt;p&gt;《智繪童話》是一款微信小程序，它巧妙地將AI技術融入到兒童教育和家庭親子活動中，通過先進的AI算法，根據孩子的興趣和喜好推薦個性化故事內容，配以動人的聲音和精美的圖像，為孩子們創造出獨一無二的故事體驗。每一個環節都力求完美，真正實現了「故事自由」的理念。&lt;/p&gt;
&lt;p&gt;我們知道，家長們在選擇教育內容時，總希望能夠提供既富有想象力又具有教育意義的素材。《智繪童話》正是基於這一需求而生。它不僅能夠根據不同年齡段的孩子身心特點定製故事，還能通過精準的AI標籤，讓您用最簡單的詞彙就能找到所需的資源。更加令人興奮的是，這些故事都是中英雙語的，不僅能夠豐富孩子的語言環境，還能在輕鬆愉快的氛圍中提高英語聽力水平。而AI語音技術的加持，更是讓故事的講述變得生動有趣，吸引孩子們的注意力，同時也讓忙碌的家長們能夠在繁重的育兒任務中稍作喘息。&lt;/p&gt;
&lt;p&gt;《智繪童話》不僅僅是一款產品，它是一個家庭親子互動的新平臺，是AI技術與日常生活完美結合的實例。在這裡，每一個家庭都能找到共同的樂趣。&lt;/p&gt;
&lt;p&gt;目前，《智繪童話》正處於公測階段，我們誠邀您與孩子一起探索這個充滿想象力的童話世界。目前我們只上線了基礎功能，在未來，我們將不斷更新迭代，引入更多智能化功能，以期為您和孩子帶來更加豐富、便捷的親子互動體驗。AI時代，讓我們一起走進這個智慧的童話世界，探索知識的海洋，共繪美好的記憶。《智繪童話》期待與您和孩子一同成長，一起創造無限可能！&lt;/p&gt;
&lt;p&gt;這是網頁版，其中點擊故事可以跳轉到小程序：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhihuitonghua.baiyan.tech/" target="_blank" rel="noopener"&gt;zhihuitonghua.baiyan.tech&lt;/a&gt;&lt;/p&gt;</description></item><item><title>假如杭州保留了南宋古建築…</title><link>https://ceeji.net/zh-hant/blog/photo-if-hangzhou-has-old-building/</link><pubDate>Sun, 28 Jan 2024 14:43:07 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/photo-if-hangzhou-has-old-building/</guid><description>&lt;p&gt;今天我使用人工智慧繪圖還原了南宋古建築和現代城市交相輝映下的杭州，一起來看：
&lt;figure&gt;
&lt;a href="0d5e129f-ef62-4ab4-8a31-1230c1a46381--qm2h2u4gg0wr0bpbftsrso6k4f8s1b20p9jjbmen937dgbukg1x9rt6xlf6gs62c.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/0d5e129f-ef62-4ab4-8a31-1230c1a46381--qm2h2u4gg0wr0bpbftsrso6k4f8s1b20p9jjbmen937dgbukg1x9rt6xlf6gs62c.png"/&gt;&lt;img title="杭州夜景" alt="杭州夜景" src="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/0d5e129f-ef62-4ab4-8a31-1230c1a46381--qm2h2u4gg0wr0bpbftsrso6k4f8s1b20p9jjbmen937dgbukg1x9rt6xlf6gs62c.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;杭州夜景&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="3c7c858d-cf9f-4a51-aea4-3f7bcaa29478--2ps3one121uce1ze4026w3amdzi93qtgpp1igp7yihqjbbkpbz6k7gfzlj6f1yx9.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/3c7c858d-cf9f-4a51-aea4-3f7bcaa29478--2ps3one121uce1ze4026w3amdzi93qtgpp1igp7yihqjbbkpbz6k7gfzlj6f1yx9.png"/&gt;&lt;img title="西湖邊的燈籠" alt="西湖邊的燈籠" src="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/3c7c858d-cf9f-4a51-aea4-3f7bcaa29478--2ps3one121uce1ze4026w3amdzi93qtgpp1igp7yihqjbbkpbz6k7gfzlj6f1yx9.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;西湖邊的燈籠&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="7fd2b60e-32fa-44fa-8c39-39fc8517e652--ch8wkevu9npjbcojfd6pvnmzvm5cr8503g0mh2091tpwrbd89u7br6c1o8li5yhi.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/7fd2b60e-32fa-44fa-8c39-39fc8517e652--ch8wkevu9npjbcojfd6pvnmzvm5cr8503g0mh2091tpwrbd89u7br6c1o8li5yhi.png"/&gt;&lt;img title="武林廣場與輕軌" alt="武林廣場與輕軌" src="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/7fd2b60e-32fa-44fa-8c39-39fc8517e652--ch8wkevu9npjbcojfd6pvnmzvm5cr8503g0mh2091tpwrbd89u7br6c1o8li5yhi.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;武林廣場與輕軌&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="389b6635-9ebe-42ae-947d-0b759823dbe4--9u7zo8lb7gvu99rl6ptmta79xjfajdjtphmz85ccjjewgz90hx790k5wjksao52r.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/389b6635-9ebe-42ae-947d-0b759823dbe4--9u7zo8lb7gvu99rl6ptmta79xjfajdjtphmz85ccjjewgz90hx790k5wjksao52r.png"/&gt;&lt;img title="杭州城站" alt="杭州城站" src="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/389b6635-9ebe-42ae-947d-0b759823dbe4--9u7zo8lb7gvu99rl6ptmta79xjfajdjtphmz85ccjjewgz90hx790k5wjksao52r.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;杭州城站&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="1700a1ac-f02a-4493-9160-290eb03640bd--x9wr62brd7zx4hx9fxp6eb6zh3vtrafh3i3zh8v59xhccvviubdm8iopvnlxmiwp.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/1700a1ac-f02a-4493-9160-290eb03640bd--x9wr62brd7zx4hx9fxp6eb6zh3vtrafh3i3zh8v59xhccvviubdm8iopvnlxmiwp.png"/&gt;&lt;img title="西湖與飛鳥" alt="西湖與飛鳥" src="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/1700a1ac-f02a-4493-9160-290eb03640bd--x9wr62brd7zx4hx9fxp6eb6zh3vtrafh3i3zh8v59xhccvviubdm8iopvnlxmiwp.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;西湖與飛鳥&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="d35597b1-d8bd-4e5b-b42e-c8ef89580fde--q0bh0ximkp9ntiifjyce1q2obyxnjo6qhugcjl7x4e365narbm55eibf9r1yz326.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/d35597b1-d8bd-4e5b-b42e-c8ef89580fde--q0bh0ximkp9ntiifjyce1q2obyxnjo6qhugcjl7x4e365narbm55eibf9r1yz326.png"/&gt;&lt;img title="高鐵穿過群山" alt="高鐵穿過群山" src="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/d35597b1-d8bd-4e5b-b42e-c8ef89580fde--q0bh0ximkp9ntiifjyce1q2obyxnjo6qhugcjl7x4e365narbm55eibf9r1yz326.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;高鐵穿過群山&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;
&lt;a href="e6f56b84-f8ff-4699-8dba-caf4e2c941bf--uv65clb97lxx7cifxpejfwr5rwqnsg4a3pt690omaeno0uzrk5z2qnemphypv7p9.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/e6f56b84-f8ff-4699-8dba-caf4e2c941bf--uv65clb97lxx7cifxpejfwr5rwqnsg4a3pt690omaeno0uzrk5z2qnemphypv7p9.png"/&gt;&lt;img title="在街巷遊玩的孩子" alt="在街巷遊玩的孩子" src="https://ceeji.net/blog/photo-if-hangzhou-has-old-building/e6f56b84-f8ff-4699-8dba-caf4e2c941bf--uv65clb97lxx7cifxpejfwr5rwqnsg4a3pt690omaeno0uzrk5z2qnemphypv7p9.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;在街巷遊玩的孩子&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>使用ChineseGenie學習中文</title><link>https://ceeji.net/zh-hant/blog/%E4%BD%BF%E7%94%A8chinesegenie%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87/</link><pubDate>Fri, 16 Jun 2023 09:04:12 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/%E4%BD%BF%E7%94%A8chinesegenie%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87/</guid><description>&lt;p&gt;革命性地學習中文，由先進的AI技術、自然語言處理和語音識別能力驅動！隨時隨地與您的AI中文口語夥伴Viva聊天，談論您最喜歡的書籍、法式餐廳等等。Viva具有與母語人士相同的地道普通話發音，但無需像真正的中文老師一樣預約時間。始終在線且可用，無需擔心按小時收費。 被一句你無法閱讀或理解的句子難倒了嗎？Viva將立即將其準確翻譯成您的母語。自信地說話，因為Viva在那裡糾正語法錯誤；需要寫一篇中文報告嗎？Viva將幫助您潤色句子，不僅修復語法問題，還解決任何不當的用詞。 Viva，您的中文精靈，是您學習語言過程中忠實的AI助手。通過ChineseGenie應用程序，發現一種全新、有趣且有效的方法來掌握中文！&lt;/p&gt;
&lt;p&gt;訪問 ChineseGenie 官網：&lt;a href="https://chinese-language-learning-chinesegenie.baiyan.tech/" target="_blank" rel="noopener"&gt;https://chinese-language-learning-chinesegenie.baiyan.tech/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>無法在阿里雲控制檯被使用的 CSI 插件特性：動態 NAS 存儲池</title><link>https://ceeji.net/zh-hant/blog/%E6%97%A0%E6%B3%95%E5%9C%A8%E9%98%BF%E9%87%8C%E4%BA%91%E6%8E%A7%E5%88%B6%E5%8F%B0%E8%A2%AB%E4%BD%BF%E7%94%A8%E7%9A%84-csi-%E6%8F%92%E4%BB%B6%E7%89%B9%E6%80%A7%EF%BC%9A%E5%8A%A8%E6%80%81-nas-%E5%AD%98/</link><pubDate>Tue, 15 Dec 2020 16:56:37 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/%E6%97%A0%E6%B3%95%E5%9C%A8%E9%98%BF%E9%87%8C%E4%BA%91%E6%8E%A7%E5%88%B6%E5%8F%B0%E8%A2%AB%E4%BD%BF%E7%94%A8%E7%9A%84-csi-%E6%8F%92%E4%BB%B6%E7%89%B9%E6%80%A7%EF%BC%9A%E5%8A%A8%E6%80%81-nas-%E5%AD%98/</guid><description>&lt;p&gt;在 Kubernetes 環境中，阿里雲早已開發並支持基於 CSI 存儲插件的動態 NAS PV 創建，其基於阿里開發的 CSI Plugin。但是，你會發現，在阿里雲的控制檯中，如果你創建 PVC，你會發現只有雲盤才支持基於 StorageClass 自動生成 PV。其實你是可以通過命令行的方式來開啟該功能的。 網上有些阿里官方的文檔比較老，一些步驟裡引用的鏈接不正確。目前創建的阿里 Kubernetes 集群都已經開啟了 CSI Plugin 並且包含 NAS 支持，你並不需要手工安裝。&lt;/p&gt;
&lt;p&gt;首先要求用戶使用NAS控制檯 或 SDK/API 創建好NAS文件系統和掛載點。&lt;/p&gt;
&lt;p&gt;然後，唯一需要的是創建一個 StorageClass, 詳細參數說明見：https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/blob/master/docs/nas-dynamic.md&lt;/p&gt;</description></item><item><title>HTML disabled 屬性的一個坑</title><link>https://ceeji.net/zh-hant/blog/html-disabled-attribute/</link><pubDate>Sat, 26 Nov 2016 02:36:18 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/html-disabled-attribute/</guid><description>&lt;p&gt;一天我在一個頁面裡寫下如下的代碼：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;並在 CSS 中設置：&lt;code&gt;#xx:disabled { background-color: red; }&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;可是，此 CSS 並沒有生效。&lt;/p&gt;
&lt;p&gt;後來考慮到，disabled 這個屬性是不是對 &lt;code&gt;div&lt;/code&gt; 無效？經過查詢，果然 disabled 屬性是針對表單的，於是果斷把 &lt;code&gt;div&lt;/code&gt; 改為 &lt;code&gt;button&lt;/code&gt;，發現依然無效。&lt;/p&gt;
&lt;p&gt;果斷在 &lt;code&gt;W3School&lt;/code&gt; 查找，發現 &lt;em&gt;disabled 屬性只對 input 元素有效&lt;/em&gt;。&lt;/p&gt;</description></item><item><title>C# 與 Java 語言機制與語法的異同</title><link>https://ceeji.net/zh-hant/blog/from-csharp-to-java-lang/</link><pubDate>Mon, 14 Nov 2016 19:06:28 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/from-csharp-to-java-lang/</guid><description>&lt;p&gt;本文是 &lt;a href="https://ceeji.net/blog/from-csharp-to-java/"&gt;從 C# 到 Java&lt;/a&gt; 系列的文章。此係列文章是為了方便從 C# 轉到 Java 平臺的工程師快速學習新的語言和平臺。&lt;strong&gt;整個系列的目錄&lt;a href="https://ceeji.net/blog/from-csharp-to-java/"&gt;請點擊此處瀏覽&lt;/a&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;這篇文章從基礎的語言機制、語法層面來分析 C# 和 Java 的不同。部分與虛擬機（CLR | JVM）有關的不同會放在相關的另一篇裡，詳見總目錄。&lt;/p&gt;
&lt;h1 id="命名規範"&gt;命名規範&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;Java&lt;/code&gt; 中的方法和變量，無論是否為&lt;code&gt;public&lt;/code&gt;，都要以小寫字母開頭，其餘與 &lt;code&gt;C#&lt;/code&gt; 大體相當。&lt;/p&gt;
&lt;h1 id="那些簡單的同義詞或近義詞"&gt;那些簡單的同義詞或近義詞&lt;/h1&gt;
&lt;p&gt;下面的詞彙，在 &lt;code&gt;Java&lt;/code&gt; 和 &lt;code&gt;C#&lt;/code&gt; 中是 &lt;code&gt;同義&lt;/code&gt; 或 &lt;code&gt;近義&lt;/code&gt; 的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C# 中獲取一個對象的類型使用 &lt;code&gt;typeof&lt;/code&gt; 關鍵詞，Java 中使用 &lt;code&gt;.class&lt;/code&gt;，如 &lt;code&gt;String.class&lt;/code&gt;；C# 也可以使用對象實例的 &lt;code&gt;GetType&lt;/code&gt; 方法，Java 中對應的是 &lt;code&gt;getClass&lt;/code&gt; 方法。&lt;a href="http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" target="_blank" rel="noopener"&gt;參考鏈接&lt;/a&gt;；&lt;/li&gt;
&lt;li&gt;代表一個對象的類型的類型，C# 為 &lt;code&gt;Type&lt;/code&gt; 類型，Java 則為 &lt;code&gt;Class&lt;/code&gt; 類型。&lt;a href="http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" target="_blank" rel="noopener"&gt;參考鏈接&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;C# 中的 &lt;code&gt;const&lt;/code&gt; （編譯時常量）和 &lt;code&gt;readonly&lt;/code&gt;（運行時常量）在 &lt;code&gt;Java&lt;/code&gt; 中都是 &lt;code&gt;final&lt;/code&gt;，同時還代表了一個類不能被繼承（等同於 &lt;code&gt;C#&lt;/code&gt; 的 &lt;code&gt;sealed&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;Java 中的 &lt;code&gt;native&lt;/code&gt; 關鍵字（聲明使用 native 實現的代碼）類似於 C# 中的 &lt;code&gt;extern&lt;/code&gt;（當聲明非託管的外部方法，如動態鏈接庫時使用）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;string&lt;/code&gt; 與 &lt;code&gt;String&lt;/code&gt;：在 Java 只有後者，在 C# 中前後兩者是同義詞。&lt;/li&gt;
&lt;li&gt;Java 中的 &lt;code&gt;synchronized&lt;/code&gt; 等同於 C# 語句塊中的 &lt;code&gt;lock&lt;/code&gt;，以及 方法體上的特性&lt;code&gt;MethodImplOptions.Synchronized&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;Java 中的 &lt;code&gt;transient&lt;/code&gt; （短暫）等同於 C# 的 &lt;code&gt;NonSerializableAttribute&lt;/code&gt;，代表在序列化中跳過。&lt;/li&gt;
&lt;li&gt;Java 的 &lt;code&gt;...&lt;/code&gt; 操作符等同於 C# 的 &lt;code&gt;params&lt;/code&gt;。例如：&lt;code&gt;String... args&lt;/code&gt;，則 args 為一個所有參數組成的數組。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="值類型與裝箱"&gt;值類型與裝箱&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;Java&lt;/code&gt; 的值類型（Value Types）僅限於原生類型，如 &lt;code&gt;int&lt;/code&gt;、&lt;code&gt;boolen&lt;/code&gt; 等。&lt;code&gt;Java&lt;/code&gt; 不允許自定義值類型，即 &lt;code&gt;Java&lt;/code&gt; 不存在 C# 中的 &lt;code&gt;struct&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;值類型&lt;/code&gt; 的作用可以從以下幾個方面來考慮：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;性能：C# 中的 &lt;code&gt;struct&lt;/code&gt; 類型有助於減少 GC、減少內存使用、提高性能，但 &lt;code&gt;Java&lt;/code&gt; 強大的虛擬機 &lt;code&gt;JVM&lt;/code&gt; 通過優化部分緩解了這個問題。&lt;/li&gt;
&lt;li&gt;語義：原生類型無法為 &lt;code&gt;null&lt;/code&gt;，且通過傳值方式賦值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是，由於 C# 中的值類型通過傳值類型賦值造成了意外錯誤的可能（例如用類似類的方式在杯傳遞後的值類型中修改成員，試圖影響到原有的值），使用值類型要警惕。&lt;/p&gt;
&lt;p&gt;值類型在 &lt;code&gt;Java&lt;/code&gt; 中不繼承於 Object，但 C# 中卻繼承，這是通過自動裝箱實現的。Java 的值類型可以通過裝箱變為類實例，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;int&lt;/code&gt; =&amp;gt; &lt;code&gt;Integer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;float&lt;/code&gt; =&amp;gt; &lt;code&gt;Float&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;byte&lt;/code&gt; =&amp;gt; &lt;code&gt;Byte&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;Java&lt;/code&gt; 具體的數據類型方面的內容，可以參考本系列文章中的另一篇：數據結構（文章末尾有目錄導航）。&lt;/p&gt;
&lt;h1 id="泛型"&gt;泛型&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;Java&lt;/code&gt; 支持泛型，但其支持的方式和 &lt;code&gt;.NET&lt;/code&gt; 差別比較大。&lt;code&gt;Java&lt;/code&gt; 的泛型使用 &lt;code&gt;類型擦除&lt;/code&gt; 實現。所以，你雖然可以設置某個方法或類有一個類型參數 &lt;code&gt;T&lt;/code&gt;，但是你在其實現內部卻無法獲知與該類型的任何信息，解決方法就是使用一個補償的 &lt;code&gt;class&lt;/code&gt; 類型（類似於 C# 中的 &lt;code&gt;Type&lt;/code&gt; 類型）參數手工傳遞數據類型。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://segmentfault.com/a/1190000003831229" target="_blank" rel="noopener"&gt;有關 Java 泛型的類型擦除，請參考鏈接&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="委託事件"&gt;委託，事件&lt;/h1&gt;
&lt;p&gt;C# 中的委託（&lt;code&gt;delegate&lt;/code&gt;）用於指向固定某個方法原型（一系列參數、某種返回值）的指針（姑且這麼叫吧）。&lt;code&gt;Java&lt;/code&gt; 中沒有 &lt;code&gt;delegate&lt;/code&gt; 的概念。&lt;/p&gt;
&lt;p&gt;Java 中一般通過接口來實現類似委託的效果。&lt;/p&gt;
&lt;p&gt;例如，&lt;code&gt;C#&lt;/code&gt; 中假如有下面的定義：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 定義委託&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;delegate&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;onClickListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 定義委託的實現&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// foo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 使用委託&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;onClickListener&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;onClickListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 Java 中可以這樣實現。先定義一個接口：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;OnClickListener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;View&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然後，使用這個接口來存儲一個&lt;code&gt;匿名類&lt;/code&gt;，其中帶有具體的實現，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OnClickListener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OnClickListener&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;View&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 在此書寫代碼&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 調用接口&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;someView&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;除了使用匿名類，也可以讓某個命名類繼承此接口：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestClass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OnClickListener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;View&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 在此書寫代碼&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OnClickListener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 調用接口&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;someView&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;C# 支持事件（&lt;code&gt;event&lt;/code&gt;），其內部是通過委託來實現的。Java 中沒有事件的概念。&lt;/p&gt;
&lt;p&gt;一般來說，用於事件或委託的情況，Java 會使用&lt;code&gt;接口&lt;/code&gt;來實現。&lt;/p&gt;
&lt;p&gt;例如，C# 中的事件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;event&lt;/span&gt; &lt;span class="n"&gt;EventHandler&lt;/span&gt; &lt;span class="n"&gt;SomeEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 事件的發出者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 事件監聽&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;someInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SomeEvent&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* xxx */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;大約等價於 &lt;code&gt;Java&lt;/code&gt; 中的方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 先定義接口&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;SomeEventListener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 搞一個東西用來存儲接口的具體實現對象&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SomeEventListener&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;someEventListeners&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 在要產生事件的類中，添加一對方法用於監聽或取消監聽&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;addSomeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SomeEventListener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;someEventListeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;removeSomeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SomeEventListener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;someEventListeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 觸發事件&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;someEventListeners&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;someEventListeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;onEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 事件監聽者，使用 Java8 中才支持的 Lambd 表達式&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;someInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addSomeEventListener&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* xxx */&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 事件監聽者，使用 Java7 以前版本的 匿名類&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;someInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addSomeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SomeEventListener&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;onEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 代碼邏輯&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也可以參考&lt;a href="https://scatteredcode.wordpress.com/2011/11/24/from-c-to-java-events/" target="_blank" rel="noopener"&gt;這篇文章&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;本文是 &lt;a href="https://ceeji.net/blog/from-csharp-to-java/"&gt;從 C# 到 Java&lt;/a&gt; 系列的文章。此係列文章是為了方便從 C# 轉到 Java 平臺的工程師快速學習新的語言和平臺。&lt;strong&gt;整個系列的目錄&lt;a href="https://ceeji.net/blog/from-csharp-to-java/"&gt;請點擊此處瀏覽&lt;/a&gt;&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>為什麼要從 C# 轉為 Java：淺談 .NET 與 Java 生態</title><link>https://ceeji.net/zh-hant/blog/from-csharp-to-java-platform/</link><pubDate>Mon, 14 Nov 2016 17:46:28 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/from-csharp-to-java-platform/</guid><description>&lt;p&gt;本文是 &lt;a href="https://ceeji.net/blog/from-csharp-to-java/"&gt;從 C# 到 Java&lt;/a&gt; 系列的第一篇文章。整個系列的目錄&lt;a href="https://ceeji.net/blog/from-csharp-to-java/"&gt;請點擊此處瀏覽&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C#&lt;/code&gt; 是 .NET 平臺上最重要的一門語言，&lt;code&gt;Java&lt;/code&gt; 是世界上使用最廣的語言之一。這兩門語言有著太多的恩怨情仇，也有很多相似之處。&lt;code&gt;C#&lt;/code&gt; 在最初創立的時候，或多或少借鑑了 &lt;code&gt;Java&lt;/code&gt; 語言的優秀特性，但後期發展又和 &lt;code&gt;Java&lt;/code&gt; 走上了不同的道路。&lt;/p&gt;
&lt;p&gt;那麼，為什麼你要從一門語言，轉換為另一門很相似的語言呢？本文主要談談，為什麼在某些情況下，你可能需要，或者願意從基於 .NET 的 &lt;code&gt;C#&lt;/code&gt; 轉移到基於 JVM 的 &lt;code&gt;Java&lt;/code&gt; 語言平臺。&lt;/p&gt;
&lt;h1 id="統一開發平臺重用現有資產"&gt;統一開發平臺，重用現有資產&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;某些類型的開發不得不用 &lt;code&gt;Java&lt;/code&gt; 開發，或者大多數人都在用 &lt;code&gt;Java&lt;/code&gt; 開發。如 Android 開發，Android 的開發技術棧全部構建於 JVM 之上；所以整個團隊的開發語言只能遷就於上述原因來選用 Java；&lt;/li&gt;
&lt;li&gt;很多團隊或公司中，有大量現存的基於 Java 的資產（代碼、模塊、應用），統一開發語言和平臺可以&lt;strong&gt;降低團隊磨合、學習成本，重用現有代碼資產&lt;/strong&gt;。而統一語言時顯然無法選擇 C#，因為 Java 適用面更廣（即很少有 &lt;code&gt;Java&lt;/code&gt; 可做而 &lt;code&gt;C#&lt;/code&gt; 無法做的領域或平臺）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="減少技術風險方便技術學習"&gt;減少技術風險，方便技術學習&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Java 的歷史更長，開發人員更多，社區也更大，如果在開發上遇到問題，有很多成熟的解決方案可以參考（俗稱的Google之）；&lt;/li&gt;
&lt;li&gt;開發特定領域的程序時，Java 可借鑑的代碼和框架更多，避免遇到技術死角；大多數領域的開發已經在 Java 中有成功的案例，避免技術上潛在的風險。&lt;/li&gt;
&lt;li&gt;某些第三方產品或接口，官方優先支持 Java 或只支持 Java，使用其他平臺需要額外開發或進行封裝，導致開發效率和性能的問題。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="減少開支"&gt;減少開支&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;靠譜的 Java 程序員更好招聘，可以減少用於招聘的人力資源成本；原因有二。一是 C# 確實比 Java 對開發者更貼心，所以導致了學習成本更低，造成了 C# 小白喪失了繼續學習的進取心，客觀上降低了 C# 開發者的平均水平；二是從絕對數量上來說，C# 開發者也少於 Java 開發者（如下圖）。&lt;/li&gt;
&lt;li&gt;基於 .NET 平臺的開發工具和相關產品普遍需要付費；基於 Java 的開發工具和相關產品免費的更多。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下圖為 2016年11月，在全球範圍內 C# 與 Java 語言的流行度對比，Java 排名第一，C# 排第四。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;a href="http://ogca4b43x.bkt.clouddn.com/0716eeb9400de220c13a5fda87b0855f.png" target="_blank" class="no-a-style"&gt;
&lt;picture&gt;
&lt;source srcset="http://ogca4b43x.bkt.clouddn.com/0716eeb9400de220c13a5fda87b0855f.png"/&gt;&lt;img title="C# 與 Java 流行度對比" alt="C# 與 Java 流行度對比" src="http://ogca4b43x.bkt.clouddn.com/0716eeb9400de220c13a5fda87b0855f.png"&gt;
&lt;/picture&gt;
&lt;/a&gt;&lt;figcaption&gt;&lt;span&gt;C# 與 Java 流行度對比&lt;/span&gt;&lt;span class="exif" title=" "&gt; &lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1 id="基於-java-開發將擁抱更廣泛的生態"&gt;基於 Java 開發將擁抱更廣泛的生態&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;如上圖所示，Java 長期在開發語言排行榜中流行程度排名第一，所以擁有更好的生態，即有&lt;strong&gt;成千上萬的成熟類庫&lt;/strong&gt;、&lt;strong&gt;大量的技術資料&lt;/strong&gt;、&lt;strong&gt;很多的現成代碼&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;Java 更偏向於基於 &lt;code&gt;Linux/Unix&lt;/code&gt; 平臺的開發，而 .NET 在早期太多地依賴於 Windows，後期 .NET &lt;strong&gt;雖然開源且跨平臺，但已為時略晚&lt;/strong&gt;。在互聯網相關行業，Linux 及其生態圈比 Windows 繁榮得多。&lt;/li&gt;
&lt;li&gt;Java 早已不是一個開發語言，而是&lt;strong&gt;一整個生態圈&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;Java 在語法、平臺技術上、開發效率上並非最好的，但卻是夠用的，且有出色的平衡性。雖然 Java 在哪個方面幾乎都不是最強的，但卻都說得過去。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;說實話，我個人更偏愛 .NET 技術，其炫酷、性能優異、免費且跨平臺、開發效率高，但是，基於以上原因，有時 Java 是更務實的選擇。&lt;/p&gt;
&lt;p&gt;如果你準備好了基於 Java，而不是 C# 開啟你的下一段代碼，就讓我們一起來學習吧！&lt;/p&gt;
&lt;p&gt;本文是 &lt;a href="https://ceeji.net/blog/from-csharp-to-java/"&gt;從 C# 到 Java&lt;/a&gt; 系列的第一篇文章。&lt;strong&gt;整個系列的目錄&lt;a href="https://ceeji.net/blog/from-csharp-to-java/"&gt;請點擊此處瀏覽&lt;/a&gt;&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>從 C# 到 Java：總目錄</title><link>https://ceeji.net/zh-hant/blog/from-csharp-to-java/</link><pubDate>Mon, 14 Nov 2016 17:03:02 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/from-csharp-to-java/</guid><description>&lt;h1 id="引言"&gt;引言&lt;/h1&gt;
&lt;p&gt;為了方便以前使用 &lt;code&gt;C#（.NET）&lt;/code&gt;，由於某些原因，需要學習 &lt;code&gt;Java&lt;/code&gt; （JVM），或開發基於其的應用的人（比如開發 Android 應用），我打算寫一篇系列文章，詳細地描述中間可能遇到地問題、學習路徑等。方便 .NET 開發人員快速轉為 Java 開發人員。&lt;/p&gt;
&lt;p&gt;具體來說，主要會通過對比和舉例來行文。在過程中，不但會講 &lt;code&gt;Java&lt;/code&gt;，也會把 &lt;code&gt;C#&lt;/code&gt;（&lt;code&gt;.NET&lt;/code&gt;） 的一些內容講一講，算是起到兩種語言甚至是平臺的對比與深入。&lt;/p&gt;
&lt;p&gt;下面是總目錄，沒寫好的部分不可點擊，有鏈接的部分才可以閱讀。&lt;/p&gt;
&lt;h1 id="總目錄"&gt;總目錄&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://ceeji.net/zh-hant/blog/from-csharp-to-java-platform"&gt;為什麼要從 C# 轉為 Java：淺談 .NET 與 Java 生態&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ceeji.net/zh-hant/blog/from-csharp-to-java-lang"&gt;C# 與 Java 語言機制與語法的異同&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;.NET 與 Java 數據結構異同 .NET 與 Java 核心類庫的主要區別 CLR 與 JVM 對比&lt;/p&gt;
&lt;p&gt;從 C# 到 Java：Java 包管理、主要框架與測試 從 C# 到 Java：開發範式與哲學&lt;/p&gt;</description></item><item><title>近期遇到的幾個佈局兼容性彙總</title><link>https://ceeji.net/zh-hant/blog/layout-compatibility-1611/</link><pubDate>Thu, 10 Nov 2016 17:59:42 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/layout-compatibility-1611/</guid><description>&lt;p&gt;（實時更新）&lt;/p&gt;
&lt;h1 id="flex-可伸縮元素比例不正確android-40---43ios-低版本"&gt;flex 可伸縮元素比例不正確（Android 4.0 - 4.3，iOS 低版本）&lt;/h1&gt;
&lt;p&gt;使用 flex 佈局，在現階段已經是非常靠譜的方案了，因為 flex 佈局已經在大多數主流瀏覽器中兼容。但是，flex 佈局還是有不少需要注意的兼容問題。&lt;/p&gt;
&lt;p&gt;在 Android 4.0 - 4.3 和部分低版本 iOS 中，可伸縮元素（大小按比例縮放的元素）如果要確保比例正確，必須設置：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;xxx&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中，&lt;code&gt;width&lt;/code&gt;，一般設置為 &lt;code&gt;width: 0&lt;/code&gt; 或 1px、0.001% 等。&lt;/p&gt;
&lt;p&gt;如果不設置，那麼一旦 flex 的子元素的實際內容超過了按照伸縮比例應該擁有的寬度，在這些有 bug 的系統中就會出問題，具體表現是**子元素的寬度將根據實際寬度進行延伸，最多可以佔據整個屏幕的寬度（即使它的 flex 佈局的父元素設置了寬度，它自身仍然可以撐開以達到整個屏幕的寬度）。&lt;/p&gt;</description></item><item><title>Javascript 中的 undefined 與 未定義（not defined）</title><link>https://ceeji.net/zh-hant/blog/javascript-%E4%B8%AD%E7%9A%84-undefined-%E4%B8%8E-%E6%9C%AA%E5%AE%9A%E4%B9%89%EF%BC%88not-defined%EF%BC%89/</link><pubDate>Mon, 01 Sep 2014 08:19:26 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/javascript-%E4%B8%AD%E7%9A%84-undefined-%E4%B8%8E-%E6%9C%AA%E5%AE%9A%E4%B9%89%EF%BC%88not-defined%EF%BC%89/</guid><description>&lt;p&gt;在 Javascript 中，有一種致命錯誤非常常見，即 &lt;code&gt;ReferenceError&lt;/code&gt;：xxx is not defined. 但是，有時候當一個值從未被賦值的時候，並不會出錯，而是返回 &lt;code&gt;undefined&lt;/code&gt;，有必要對這兩者進行梳理。&lt;/p&gt;
&lt;h1 id="undefined"&gt;undefined&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;undefined&lt;/code&gt; 表達的含義有三種情況：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;這個變量&lt;strong&gt;存在&lt;/strong&gt;，但是並沒有給予任何值。&lt;/li&gt;
&lt;li&gt;一種普通的數據類型和一種值。你可以手工將任何變量賦值為 undefined，此時其沒有特別含義。&lt;/li&gt;
&lt;li&gt;一個&lt;strong&gt;存在的對象&lt;/strong&gt;中的一個&lt;strong&gt;不存在&lt;/strong&gt;（沒有聲明）的值，會被認為是 undefined。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;對這三種情況進行歸納，undefined 可以如下總結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它是一種數據類型，也是一種值。&lt;/li&gt;
&lt;li&gt;有這種值的時候，要麼它本身被賦值，要麼本身存在，要麼其所在對象存在。完全不存在的變量不會是 undefined（注意，此處還有坑，往後看）。 下面舉幾個例子。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="一個聲明但沒有賦值的變量為-undefined"&gt;一個聲明但沒有賦值的變量為 undefined&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="一個不存在的對象成員為-undefined"&gt;一個不存在的對象成員為 undefined&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果 p 還有一個成員 &lt;code&gt;b&lt;/code&gt;，其值被手工賦值為 undefined，如何區分不存在的成員 a 和存在的成員 b？可以使用 &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty" target="_blank" rel="noopener"&gt;Object.prototype.HasOwnProperty()&lt;/a&gt; 方法。&lt;/p&gt;
&lt;h2 id="一個手工賦值的-undefined"&gt;一個手工賦值的 undefined&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;從上面的三個例子可以清楚看出 &lt;code&gt;undefined&lt;/code&gt; 的一些情況。undefined 的優點在於正常使用有此值的變量不會拋出異常。&lt;/p&gt;
&lt;h1 id="未定義not-defined"&gt;未定義（not defined）&lt;/h1&gt;
&lt;p&gt;一個 &lt;code&gt;未定義&lt;/code&gt; (not defined) 的變量是&lt;strong&gt;完全沒有任何聲明&lt;/strong&gt;的變量。這樣的變量在使用時會直接拋出致命錯誤。但是，如果使用 typeof 來判斷這樣的變量，不但不會出錯，而且竟然會返回 &lt;code&gt;undefined&lt;/code&gt;，這使得無法使用 typeof 來區分這兩種情況。&lt;/p&gt;</description></item><item><title>iPhone 手機QQ 4.7.2 版本網絡狀態洩露用戶隱私</title><link>https://ceeji.net/zh-hant/blog/iphone-%E6%89%8B%E6%9C%BAqq-4-7-2-%E7%89%88%E6%9C%AC%E7%BD%91%E7%BB%9C%E7%8A%B6%E6%80%81%E6%B3%84%E9%9C%B2%E7%94%A8%E6%88%B7%E9%9A%90%E7%A7%81/</link><pubDate>Tue, 01 Jul 2014 15:44:42 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/iphone-%E6%89%8B%E6%9C%BAqq-4-7-2-%E7%89%88%E6%9C%AC%E7%BD%91%E7%BB%9C%E7%8A%B6%E6%80%81%E6%B3%84%E9%9C%B2%E7%94%A8%E6%88%B7%E9%9A%90%E7%A7%81/</guid><description>&lt;p&gt;iPhone 手機QQ 4.7.2 版本會在用戶的在線狀態旁邊增加一行小字，「2G」，「3G」，「4G」，或「WiFi」。我目前沒有找到關閉這項功能的方法。而這項內容其實是嚴重洩漏了用戶的隱私信息的。&lt;/p&gt;
&lt;p&gt;對於很多生活就是三點一線甚至兩點一線的人來說，其所在區域的網絡狀態（2G、3G、WiFi）可以輕易讓人確定其方位。尤其是，如果再加上電腦在線的狀態，這四種狀態很可能可以大體推斷用戶所在位置。&lt;/p&gt;
&lt;p&gt;例如對於學生黨而言：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2G：可能在旅遊或火車上。 3G、4G：可能在課堂或市區。 WiFi：很可能在寢室或圖書館。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;騰訊沒有給出取消狀態顯示的方式，對於用戶隱私考慮絕對是不周全的。&lt;/p&gt;</description></item><item><title>宋卿體育館與六一慘案</title><link>https://ceeji.net/zh-hant/blog/%E5%AE%8B%E5%8D%BF%E4%BD%93%E8%82%B2%E9%A6%86%E4%B8%8E%E5%85%AD%E4%B8%80%E6%83%A8%E6%A1%88/</link><pubDate>Sat, 19 Apr 2014 06:44:46 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/%E5%AE%8B%E5%8D%BF%E4%BD%93%E8%82%B2%E9%A6%86%E4%B8%8E%E5%85%AD%E4%B8%80%E6%83%A8%E6%A1%88/</guid><description>&lt;p&gt;在武漢大學文理學部第四教學樓前樹立著一個六一亭，紀念著當年六一慘案中的遇難者。一九四七年六月一日黎明，國民黨軍警幾千人武裝包圍了武漢大學校園。肆意搜捕進步師生陳如豐、王志德、黃鳴嵐三人，並當場慘遭槍殺，造成震驚全國的「六一」慘案。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;機槍掃射，軍警包圍，珞珈山竟成屠場，請看遍地鮮血，四項諾言何去？ 四海同胞，人神共憤，清華園遙祭英魂，謹獻一瓣心血，億萬青年繼後來。 （摘自清華學生自治會的輓聯）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同年8月，武漢大學進步師生在校內修建「六·一」慘案紀念亭。亭坐北朝南，邊高6.5米，六角地尖頂，翠瓦飛簷，有6根朱漆圓柱支柱。在六一亭上寫有紀念的碑文。&lt;/p&gt;
&lt;p&gt;其不遠處的桂園有一個著名的宋卿體育館。宋卿體育館用了「民國大總統」黎元洪的字「宋卿」作為名稱，是因為其資金來源於黎元洪之子的捐贈。&lt;/p&gt;
&lt;p&gt;然而之前我不知道的是，六一慘案的紀念儀式就是在距離其不遠的宋卿體育館舉行的。&lt;/p&gt;
&lt;p&gt;我也不知道的是，在黎元洪當年籌備十萬大洋捐建武漢大學體育館的時候，其是為了滿足自己的一個心願：能夠讓自己死後葬在風景如畫的珞珈山南麓。黎元洪希望自己的捐贈能讓武大置換給自己一塊陵墓的位置。為了得葬於此地，黎元洪曾表示願意向武大捐獻一筆資金，不過被當時的武漢大學拒絕了，老武大前輩們當年的風骨可見一斑。&lt;/p&gt;
&lt;p&gt;黎元洪早年曾想在武昌創辦江漢大學，並籌款銀洋10萬元購買了當時的中興煤礦股票1000股，以備日後作辦學基金。黎元洪病逝後其子將股票折換成10萬現大洋，並在1934年去信給武大稱:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;繫於先君遺志，不敢輒忘，……擬將此項基金轉移貴校，用以培植人才，藉了先君心願。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;武大派人到天津過戶並同黎子約定這筆資金用來建設宋卿體育館。&lt;/p&gt;</description></item><item><title>Nginx 無法處理軟鏈接作為網站主目錄的情況</title><link>https://ceeji.net/zh-hant/blog/nginx-soft-link-as-website-root-permission-denied/</link><pubDate>Wed, 16 Apr 2014 04:28:52 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/nginx-soft-link-as-website-root-permission-denied/</guid><description>&lt;p&gt;近日我將本站點的服務器從北京遷移到了廣州。在遷移的過程中，我發現 Nginx 無法處理軟鏈接作為網站主目錄的情況。&lt;/p&gt;
&lt;p&gt;例如，我在 Dropbox 備份了服務器的網站主目錄，位置在 &lt;code&gt;/root/Dropbox/var/www&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;我使用這條命令為其創建一個軟鏈接：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ln -s /root/Dropbox/var/www /var/www&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;修改目錄和軟鏈接的所有者以便 nginx 可以讀取和執行：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;chown -h www-data:www-data /var/www&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;chown -R www-data:www-data /root/Dropbox/var/www&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;然後，修改 nginx 配置文件中 &lt;code&gt;sites-enabled&lt;/code&gt; 的網站，把其配置中的主目錄設定為 &lt;code&gt;/var/www&lt;/code&gt;；&lt;/p&gt;
&lt;p&gt;隨後運行，發現 nginx 報告 500 錯誤，查看 nginx 日誌 &lt;code&gt;/var/log/nginx/error.log&lt;/code&gt;，發現其中有這樣的話：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;13: Permision Denied
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;經過仔細檢查，我認定無論如何設置權限， nginx 都無法處理軟鏈作為主目錄的情況。&lt;/p&gt;</description></item><item><title>甲午年，至關重要的使命</title><link>https://ceeji.net/zh-hant/blog/%E7%94%B2%E5%8D%88%E5%B9%B4%EF%BC%8C%E8%87%B3%E5%85%B3%E9%87%8D%E8%A6%81%E7%9A%84%E4%BD%BF%E5%91%BD/</link><pubDate>Thu, 30 Jan 2014 18:04:11 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/%E7%94%B2%E5%8D%88%E5%B9%B4%EF%BC%8C%E8%87%B3%E5%85%B3%E9%87%8D%E8%A6%81%E7%9A%84%E4%BD%BF%E5%91%BD/</guid><description>&lt;p&gt;接下來的一年於我而言的重要，直接可以用人生選擇來形容。我已經將創業作為了自己的發展方向和主業。接下來的半年，算是正式創業的開端。從此，作為一個職業創業者，今年的使命可以說「亞歷山大」。 更核心的時期，應該是前半年，也就是我畢業之前的時間節點。在這段時間，我的業績能做到如何，企業能否起步，將是相當重要的一個轉折點。 加油。&lt;/p&gt;</description></item><item><title>蔡元培不肯再任北大校長的宣言</title><link>https://ceeji.net/zh-hant/blog/%E8%94%A1%E5%85%83%E5%9F%B9%E4%B8%8D%E8%82%AF%E5%86%8D%E4%BB%BB%E5%8C%97%E5%A4%A7%E6%A0%A1%E9%95%BF%E7%9A%84%E5%AE%A3%E8%A8%80/</link><pubDate>Fri, 03 Jan 2014 10:58:49 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/%E8%94%A1%E5%85%83%E5%9F%B9%E4%B8%8D%E8%82%AF%E5%86%8D%E4%BB%BB%E5%8C%97%E5%A4%A7%E6%A0%A1%E9%95%BF%E7%9A%84%E5%AE%A3%E8%A8%80/</guid><description>&lt;h1 id="1919年6月15日"&gt;（1919年6月15日）&lt;/h1&gt;
&lt;p&gt;（一）我絕對不能再作那政府任命的校長：為了北京大學校長是簡任職，是半官僚性質，便生出那許多官僚的關係，那裡用呈，那裡用諮，天天有一大堆無聊的照例的公牘。要是稍微破點例，就要呈請教育部，候他批准。什麼大學文、理科叫做本科的問題，文、理合辦的問題，選科制的問題，甚至小到法科暫省學長的問題，附設中學的問題，都要經那拘文牽義的部員來斟酌。甚而部裡還常常派了什麼一知半解的部員來視察，他報告了，還要發幾個訓令來訓飭幾句。我是個痛惡官僚的人，能甘心仰這些官僚的鼻息麼？我將進北京大學的時候，沒有想到這一層，所以兩年有半，天天受這個苦痛。現在苦痛受足了，好容易脫離了，難道還肯投入去麼？&lt;/p&gt;
&lt;p&gt;（二）我絕對不能再做不自由的大學校長：思想自由，是世界大學的通例。得意志帝政時代，是世界著名開明專制的國，他的大學何等自由。那美、法等國，更不必說了。北京大學，向來受舊思想的拘束，是很不自由的。我進去了，想稍稍開點風氣，請了幾個比較的有點新思想的人，提倡點新的學理，發佈點新的印刷品，用世界的新思想來比較，用我的理想來批評，還算是半新的。在新的一方面偶有點兒沾沾自喜的，我還覺得好笑。哪知道舊的一方面，看了這點半新的，就算&amp;quot;洪水猛獸&amp;quot;一樣了。又不能用正當的辯論法來干涉了，國務院來干涉了，甚而什麼參議院也來干涉了，世界哪有這種不自由的大學麼？還要我去充這種大學的校長麼？&lt;/p&gt;
&lt;p&gt;（三）我絕對不能再到北京的學校任校長：北京是個臭蟲窠。無論何等高尚的人物，無論何等高尚的事業，一到北京，便都染了點臭蟲的氣味。我已經染了兩年有半了，好容易逃到故鄉的西湖、鑑湖，把那個臭氣味淘洗乾淨了。難道還要我再作逐臭之夫，再去嚐嚐這氣味麼？&lt;/p&gt;
&lt;p&gt;我想有人見了我這一段的話，一定要把&amp;rsquo;我不入地獄，誰入地獄&amp;rsquo;的話來勸勉我。但是我現在實在沒有到佛說這句話的時候的程度，所以只好謹謝不敏了。&lt;/p&gt;
&lt;h1 id="附愛蔡孑民者啟"&gt;附：愛蔡孑民者啟&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;右宣言聞尚是蔡君初出京時所草，到上海後，本擬即行宣佈，後因北京挽留之電，有友人勸其婉復，免致以個人去留問題與學生所爭政治問題，永結不解之緣，故有以條件的允任維持之電，後來又有臥病不行之電，均未將真意說出。聞其意，無論如何，決不回校也。鄙人抄得此宣言書，覺與北京各報所載啟事，及津浦車站告友之言，均相符合，必是祭君本意。個人意志自由，本不可以多數壓制之，且為社會上留此一個乾淨人，使不與政治問題發生關係，亦是好事。故特為宣佈，以備挽留蔡君者之參考焉。愛蔡孑民者啟&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;據蔡元培手稿&lt;/p&gt;
&lt;p&gt;選自《蔡元培全集》第3卷，中華書局1984年版&lt;/p&gt;
&lt;h1 id="另附蔡元培先生任北京大學校長之就職演說"&gt;另附《蔡元培先生任北京大學校長之就職演說》&lt;/h1&gt;
&lt;p&gt;五年前，嚴幾道先生為本校校長時，餘方服務教育部，開學日曾有所貢獻於學校。諸君多自預科畢業而來，想必聞知。士別三日，刮目相見，況時閱數載，諸君較昔當為長足之進步矣。予今長斯校，請以三事為諸君告：&lt;/p&gt;
&lt;p&gt;一曰抱定宗旨。諸君來此求學，必有一定宗旨，欲求宗旨之正大與否，必先知大學之性質。今人肄業專門學校，學成任事，此固勢所必然。而在大學則不然，大學者，研究高深學問者也。外人每指摘本校之腐敗，以求學於此者，皆有做官發財思想，故畢業預科者，多入法科，入文科者甚少，入理科者尤少，蓋以法科為幹祿之終南捷徑也。因做官心熱，對於教員，則不問其學問之淺深，惟問其官階之大小。官階大者，特別歡迎，蓋為將來畢業有人提攜也。現在我國精於政法者，多入政界，專任教授者甚少，故聘請教員，不得不聘請兼職之人，亦屬不得已之舉。究之外人指摘之當否，姑不具論，然弭謗莫如自修，人譏我腐敗，問心無愧，於我何懼？果欲達其做官發財之目的，則北京不少專門學校，入法科者儘可肄業於法律學堂，入商科者亦可投考商業學校，又何必來此大學？所以諸君須抱定宗旨，為求學而來，入法科者，非為做官；入商科者，非為致富。宗旨既定，自趨正軌，諸君肄業於此，或三年，或四年，時間不為不多，苟能愛惜分陰，孜孜求學，則求造詣，容有底止。若徒志在做官發財，宗旨既乖，趨向自異。平時則放蕩冶遊，考試則熟讀講義，不問學問之有無，惟爭分數之多寡；試驗既終，書籍束之高閣，毫不過問，敷衍三、四年，潦草塞責，文憑到手，即可藉此活動於社會，豈非與求學初衷大相背馳乎？光陰虛度，學問毫無，是自誤也。且辛亥之役，吾人之所以革命，因清廷官吏之腐敗。即在今日，吾人對於當軸多不滿意，亦以其道德淪喪。今諸君苟不於此時植其基，勤其學，則將來萬一因生計所迫，出而仕事，但任講席，則必貽誤學生；置身政界，則必貽誤國家。是誤人也。誤已誤人，又豈本心所願乎？故宗旨不可以不正大。此餘所希望於諸君者一也。&lt;/p&gt;
&lt;p&gt;二曰砥礪德行。方今風俗日偷，道德淪喪，北京社會，尤為惡劣，敗德毀行之事，觸目皆是，非根基深固，鮮不為流俗所染。諸君肄業大學，當能束身自愛。然國家之興替，視風俗之厚薄。流俗如此，前途何堪設想。故必有卓絕之士，以?身作則，力矯頹俗，諸君為大學學生，地位甚高，肩此重任，責無旁貸，故諸君不惟思所以感已，更必有以勵人。苟德之不修，學之不講，同乎流俗，合乎汙世，已且為人輕侮，更何足以感人。然諸君終日伏首案前，芸芸攻苦，毫無娛樂之事，必感身體上之苦痛。為諸君計，莫如以正當之娛樂，易不正當之娛樂，庶幾道德無虧，而於身體有益。諸君入分科時，曾填寫願書，遵守本校規則，苟中道而違之，豈非與原始之意相反乎？故品行不可以不謹嚴。此餘所希望於諸君者二也。&lt;/p&gt;
&lt;p&gt;三曰敬愛師友。教員之教授，職員之任務，皆以圖諸君求學便利，諸君能無動於衷乎？自應以誠相待，敬禮有加。至於同學共處一室，尤應互相親愛，庶可收切磋之效。不惟開誠佈公，更宜道義相勗，蓋同處此校，譭譽共之。同學中苟道德有虧，行有不正，為社會所訾詈，已雖規行矩步，亦莫能辨，此所以必互相勸勉也。餘在德國，每至店肆購買物品，店主殷勤款待，付價接物，互相稱謝，此雖小節，然亦交際所必需，常人如此，況堂堂大學生乎？對於師友之敬愛，此餘所希望於諸君者三也。&lt;/p&gt;
&lt;p&gt;餘到校視事僅數日，校事多未詳悉，茲所計劃者二事：一曰改良講義。諸君既研究高深學問，自與中學、高等不同，不惟恃教員講授，尤賴一已潛修。以後所印講義，只列綱要，細微末節，以及精旨奧義，或講師口授，或自行參考，以期學有心得，能裨實用。二曰添購書籍。本校圖書館書籍雖多，新出者甚少，苟不廣為購辦，必不足供學生之參考。刻擬籌集款項，多購新書，將來典籍滿架，自可旁稽博採，無虞缺乏矣。今日所與諸君陳說者只此，以後會晤日長，隨時再為商榷可也。&lt;/p&gt;
&lt;p&gt;蔡元培 1917年4月&lt;/p&gt;</description></item><item><title>Mono 環境下跟蹤和優化 .NET 程序內存分配</title><link>https://ceeji.net/zh-hant/blog/mono-environment-track-dotnet-memory-alloc/</link><pubDate>Mon, 09 Dec 2013 16:40:59 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/mono-environment-track-dotnet-memory-alloc/</guid><description>&lt;p&gt;.NET 程序在 Mono 環境之下的內存分配和在 Microsoft .NET Framework 環境是不太相同的，雖然它們的兼容性很高，但仍有區別。尤其是在 GC 方面，Mono 的 GC 實現似乎仍有不足（在 3.0.6 版本下），據我觀察，有一些大對象（估計是二代對象，譬如很大的 &lt;code&gt;byte[]&lt;/code&gt; 數組）的釋放仍然有些問題。下面就以 TCP 服務器端程序為例。&lt;/p&gt;
&lt;h1 id="場景"&gt;場景&lt;/h1&gt;
&lt;p&gt;假設在服務器端有這樣的語句，用來備份 SQLite 數據庫文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;BackupDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getAllContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DBFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteAllBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Zip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Compress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;getAllContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileStream&lt;/span&gt; &lt;span class="n"&gt;fs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileAccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileShare&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadWrite&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;數據庫正在讀寫，請稍後再備份。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;備份數據庫需要讀取整個數據庫。這段代碼直接將整個數據庫的本地文件鏡像讀出，並放在了一個 &lt;code&gt;Byte[]&lt;/code&gt; 數組之中，作為 &lt;code&gt;getAllContent&lt;/code&gt; 函數的返回值。在讀取之後， &lt;code&gt;getAllContent&lt;/code&gt; 方法的 &lt;code&gt;b&lt;/code&gt; 中存儲了大量的字節。另外，在 &lt;code&gt;BackupDB&lt;/code&gt; 函數中，使用 &lt;code&gt;Zip.Compress&lt;/code&gt; 函數壓縮數據庫後，也會返回一個較大的 byte[] 數組。&lt;/p&gt;
&lt;p&gt;經過測試，這段代碼在 Windows 的 .NET Framework 平臺下工作沒有問題。因為這些大對象可以幾乎在使用後即刻被銷燬。但是，在 Mono 下，即使在代碼的最後顯式調用 &lt;code&gt;GC.Collect()&lt;/code&gt; 方法進行全代垃圾回收，也無法減少內存。&lt;/p&gt;
&lt;h1 id="使用-profiler-跟蹤內存分配和垃圾回收"&gt;使用 Profiler 跟蹤內存分配和垃圾回收&lt;/h1&gt;
&lt;p&gt;雖然我們可能不知道原因出在哪裡，但是我們可以通過 Mono 自帶的工具來跟蹤內存分配。這裡用到的工具是 &lt;a href="http://www.mono-project.com/Profiler" target="_blank" rel="noopener"&gt;Profiler&lt;/a&gt;，這個工具只支持 Mono 2.9+，如果你使用的發行版過於穩定，可能需要安裝測試版本的 Mono 或手工編譯安裝 Mono 才可以使用這個工具。&lt;/p&gt;
&lt;p&gt;Profiler 特別像在 Visual Studio 中的「性能分析」工具。它們的原理也大同小異。它們都是通過運行時採樣和日誌，來跟蹤程序運行的狀態。&lt;/p&gt;
&lt;p&gt;具體來說，Profiler 會在託管程序運行時記錄這些內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;方法進入和退出&lt;/li&gt;
&lt;li&gt;對象分配&lt;/li&gt;
&lt;li&gt;垃圾回收&lt;/li&gt;
&lt;li&gt;JIT 編譯&lt;/li&gt;
&lt;li&gt;元數據加載&lt;/li&gt;
&lt;li&gt;鎖上下文&lt;/li&gt;
&lt;li&gt;異常&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外，它還提供了&lt;strong&gt;堆快照&lt;/strong&gt;的功能，可以在你的程序進行過一次垃圾回收之後，記錄下目前託管堆的情況。&lt;/p&gt;
&lt;h2 id="使用-profile-日誌"&gt;使用 Profile 日誌&lt;/h2&gt;
&lt;p&gt;要使用 Profiler 進行分析，首先要以附加參數啟動 Mono 代碼：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mono &amp;ndash;profile=log program.exe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在程序運行結束後，在當前目錄下會生成一個 &lt;code&gt;output.mlpd&lt;/code&gt; 文件。這個文件稍後可以被用來做性能分析。在程序運行結束之後，輸入命令&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mprof-report output.mlpd&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;會生成分析報告。&lt;/p&gt;
&lt;p&gt;你也可以使用一些參數，常用參數有&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mono &amp;ndash;profile=log:report program.exe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這樣可以不保留日誌，而是直接產生分析報告，有時候這可能很有用，因為&lt;strong&gt;日誌文件實在是太大了&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mono &amp;ndash;profile=log:noalloc program.exe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;noalloc&lt;/code&gt; 會導致日誌中不記錄分配情況。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mono &amp;ndash;profile=log:nocalls program.exe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;nocalls&lt;/code&gt; 不記錄調用方法。如果不使用 nocalls，要預留足夠大的硬盤空間。在我的實驗中，幾分鐘產生了 500MB 甚至 2GB 的數據（即使取消一些日誌，文件仍然很大）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mono &amp;ndash;gc=sgen &amp;ndash;profile=log:heapshot program.exe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這可以記錄託管堆的快照。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mono &amp;ndash;profile=log:sample program.exe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;CPU 採樣，和 .NET 自帶的特別像，通過一般不超過 10% 的性能損耗，在運行時動態採樣，以便獲取關於 CPU 時間消耗在什麼運算中的第一手資料。&lt;/p&gt;
&lt;h2 id="分析日誌"&gt;分析日誌&lt;/h2&gt;
&lt;p&gt;現在我們開始分析日誌，輸入命令&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mprof-report output.mlpd&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;即可看到結果。&lt;/p&gt;
&lt;p&gt;詳細的 Mono Profiler 使用方法請參考它的&lt;a href="http://www.mono-project.com/Profiler" target="_blank" rel="noopener"&gt;官方文檔&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id="兩處優化"&gt;兩處優化&lt;/h1&gt;
&lt;h2 id="使用-stream-代替-byte"&gt;使用 Stream 代替 byte[]&lt;/h2&gt;
&lt;p&gt;如果可能，在操作大量 &lt;code&gt;byte[]&lt;/code&gt; 數據的地方，考慮使用 Stream 對象。比如，如果你使用 FileStream 操作大文件，你將不需要將文件性一次讀入內存。進行此項優化成功節約了 20% 的內存。但是要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;確保 Stream 的回收，儘可能使用 &lt;code&gt;using&lt;/code&gt; 關鍵字來管理 Stream 的釋放&lt;/li&gt;
&lt;li&gt;如果你使用的是 &lt;code&gt;MemoryStream&lt;/code&gt;，其內部實現其實是一個動態變長的 &lt;code&gt;byte[]&lt;/code&gt; 數組，當它增長到最大的時候，文件仍然是完全放在了內存之中。&lt;/li&gt;
&lt;li&gt;最重要的是，&lt;em&gt;你對數據的處理必須是流式的&lt;/em&gt;，如果你只是把 FileStream 分塊讀入到一個 &lt;code&gt;byte[]&lt;/code&gt;，&lt;code&gt;DataTable&lt;/code&gt;，&lt;code&gt;MemoryStream&lt;/code&gt; 等中並作為參數進行某種操作（比如壓縮，如上述代碼中的 Zip.Compress(byte[] 對象)），那麼你仍然無法節約內存。你必須確保你對流的操作是分塊流式進行的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;壓縮是典型的非流式操作，因為壓縮算法幾乎都是基於上下文的，而不只是當前位置。&lt;/p&gt;
&lt;h2 id="使用外部命令代替大內存操作"&gt;使用外部命令代替大內存操作&lt;/h2&gt;
&lt;p&gt;編寫另外一個可執行文件，這個文件不能是 dll，so 等模塊，保證其內存空間的獨立，然後將耗費內存的操作放在這個程序中，將數據的位置作為參數。好處是這個程序處完數據會退出，所有資源得到了充分的釋放。&lt;/p&gt;
&lt;h2 id="為什麼不使用-gccollect"&gt;為什麼不使用 GC.Collect()&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GC.Collect() 進行全代垃圾回收，暫停所有線程的運行，而且資源消耗大，對於對速度要求高的程序（比如服務器端程序）不太合適&lt;/li&gt;
&lt;li&gt;GC 未必可以正確的回收所有垃圾（如本文代碼在 Mono 環境下就無法正常回收）&lt;/li&gt;
&lt;li&gt;外置程序可以在多核計算機中和原服務器中並行執行，因為數據處理很多時候是高 IO 操作，不會卡住服務器程序，邏輯簡單性能又高&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="通過弱引用weekreference管理緩存"&gt;通過弱引用（WeekReference）管理緩存&lt;/h1&gt;
&lt;p&gt;這並不是標準庫推薦的做法，但是如果你想簡單的防止程序緩存佔用過多的資源，可以使用它。詳細介紹可以移步 MSDN。&lt;/p&gt;</description></item><item><title>VirtualBox Code CO_E_SERVER_EXEC_FAILURE Server execution failed 解決辦法</title><link>https://ceeji.net/zh-hant/blog/virtualbox-code-co_e_server_exec_failure-server-execu-tion-failed-%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/</link><pubDate>Wed, 04 Dec 2013 22:45:39 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/virtualbox-code-co_e_server_exec_failure-server-execu-tion-failed-%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/</guid><description>&lt;h1 id="問題描述"&gt;問題描述&lt;/h1&gt;
&lt;p&gt;如果你在使用 VirtualBox 的命令行 &lt;code&gt;VBoxManage&lt;/code&gt; 創建虛擬磁盤指向物理磁盤，那麼你&lt;a href="http://wishuwell.blog.163.com/blog/static/182950146201332892928812/" target="_blank" rel="noopener"&gt;可能會使用類似這樣的語法&lt;/a&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;VBoxManage internalcommands createrawvmdk -filename &amp;#34;C:\Users\my\usb30.vmdk&amp;#34; -rawdisk &amp;#34;\\.\PhysicalDrive1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中，&lt;em&gt;filename&lt;/em&gt; 代表的是虛擬磁盤名稱，&lt;em&gt;rawdisk&lt;/em&gt; 代表的是對應的物理磁盤，PhysicalDrive1 代表的是&lt;strong&gt;第二塊物理磁盤（通常是移動硬盤）&lt;/strong&gt;，請不要搞錯了，直接複製來用。&lt;/p&gt;
&lt;p&gt;此時（在 Windows 平臺下），你可能會得到這樣的錯誤輸出。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;VBoxManage.exe: error: Code CO_E_SERVER_EXEC_FAILURE (0x80080005) - Server execution failed (extended info not available)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="解決方法"&gt;解決方法&lt;/h1&gt;
&lt;p&gt;解決方法只是把每個參數加上引號，很無語，因為其實並沒有空格等字符，但仍然需要加上引號，而且錯誤信號驢頭不對馬嘴。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;VBoxManage internalcommands createrawvmdk -filename &amp;ldquo;C:\Users\my\usb30.vmdk&amp;rdquo; -rawdisk &amp;ldquo;\.\PhysicalDrive1&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;輸出：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RAW host disk access VMDK file C:\Users\my\usb30.vmdk created successfully.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;另，如果你執行 VBoxManage 遇到 Access Denied 等錯誤，請用管理員權限打開 cmd。&lt;/p&gt;
&lt;h1 id="參考資料"&gt;參考資料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://wishuwell.blog.163.com/blog/static/182950146201332892928812/" target="_blank" rel="noopener"&gt;http://wishuwell.blog.163.com/blog/static/182950146201332892928812/&lt;/a&gt; VirtualBox中引導usb啟動盤&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.sina.com.cn/s/blog_7d0164e301011d10.html" target="_blank" rel="noopener"&gt;http://blog.sina.com.cn/s/blog_7d0164e301011d10.html&lt;/a&gt; VirtualBox直接使用物理硬盤作虛擬機磁盤&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>在 Debian Wheely (6.0) 下安裝 testing mono 軟件包</title><link>https://ceeji.net/zh-hant/blog/%E5%9C%A8-debian-wheely-6-0-%E4%B8%8B%E5%AE%89%E8%A3%85-testing-mono-%E8%BD%AF%E4%BB%B6%E5%8C%85/</link><pubDate>Tue, 03 Dec 2013 08:09:26 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/%E5%9C%A8-debian-wheely-6-0-%E4%B8%8B%E5%AE%89%E8%A3%85-testing-mono-%E8%BD%AF%E4%BB%B6%E5%8C%85/</guid><description>&lt;p&gt;在 /etc/apt/sources.list.d/下建立一個 testing.list 文件，內容為&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;deb &lt;a href="http://ftp.cn.debian.org/debian" target="_blank" rel="noopener"&gt;http://ftp.cn.debian.org/debian&lt;/a&gt; testing main&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然後執行&lt;/p&gt;
&lt;p&gt;apt-get update&lt;/p&gt;
&lt;p&gt;apt-get -t testing install 包名&lt;/p&gt;
&lt;p&gt;即可。&lt;/p&gt;</description></item><item><title>PHP 獲取 EXIF 信息時中文編碼問題</title><link>https://ceeji.net/zh-hant/blog/php-%E8%8E%B7%E5%8F%96-exif-%E4%BF%A1%E6%81%AF%E6%97%B6%E4%B8%AD%E6%96%87%E7%BC%96%E7%A0%81%E9%97%AE%E9%A2%98/</link><pubDate>Sun, 01 Dec 2013 20:47:05 +0000</pubDate><guid>https://ceeji.net/zh-hant/blog/php-%E8%8E%B7%E5%8F%96-exif-%E4%BF%A1%E6%81%AF%E6%97%B6%E4%B8%AD%E6%96%87%E7%BC%96%E7%A0%81%E9%97%AE%E9%A2%98/</guid><description>&lt;p&gt;在 Windows 中編輯的 EXIF 信息（指的是資源管理器之中編輯的）默認存儲為 Unicode，但是&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Unicode 編碼並不等於 UTF-8 編碼。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，在 PHP 中進行如下轉換：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;iconv(&amp;ldquo;unicode&amp;rdquo;, &amp;ldquo;utf8&amp;rdquo;, xxxxx);&lt;/p&gt;
&lt;/blockquote&gt;</description></item></channel></rss>