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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,40 @@ jobs:
-e "ssh -i ~/.ssh/deploy_key -p ${SERVER_PORT:-22} -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o PubkeyAcceptedAlgorithms=+ssh-rsa" \
./website/public/ \
"${SSH_USERNAME}@${SSH_HOST}:${SERVER_DESTINATION:-/var/www/books/leetcode/}"

word-count: # 重新统计总字数并把 README 里的徽章数字刷新、自动提交回仓库
# 只在 master 上跑(add_hugo 等分支不自动改 README)。
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
permissions:
contents: write # 需要写权限才能 commit & push 回仓库
steps:
- uses: actions/checkout@v5

- name: Compute total word count # 跑仓库自带脚本(标准库即可,ubuntu-latest 自带 python3)
id: wc
run: |
COUNT=$(python3 website/content/ChapterFour/pytool/WordCount.py | awk '/total word count/{print $NF}')
# 防御:脚本异常时不要用空值/非数字去覆盖徽章
if ! echo "$COUNT" | grep -qE '^[0-9]+$'; then
echo "WordCount.py 未返回有效数字:'$COUNT'"; exit 1
fi
echo "total word count = $COUNT"
echo "count=$COUNT" >> "$GITHUB_OUTPUT"

- name: Update badge & commit if changed
run: |
# 只替换 README 里 Total Word Count 徽章的数字部分
COUNT="${{ steps.wc.outputs.count }}"
sed -i -E "s#(Total%20Word%20Count-)[0-9]+(-success)#\1${COUNT}\2#" README.md
if git diff --quiet -- README.md; then
echo "徽章已是最新(${COUNT}),无需提交。"
else
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add README.md
# [skip ci]:这次只改 README 的自动提交不必再触发任何 workflow(deploy 已 paths-ignore,
# 但 test.yml 没有,所以统一用 skip ci 防止多余构建,也彻底杜绝循环触发)。
git commit -m "chore: update Total Word Count badge to ${COUNT} [skip ci]"
git push
fi
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,27 @@
![](./website/static/wechat-qr-code.png)

<p align='center'>
<a href="https://github.com/halfrost/leetcode-go/releases/" rel="nofollow"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/halfrost/LeetCode-Go/total?label=PDF%20downloads"></a>
<img src="https://img.shields.io/badge/Total%20Word%20Count-738884-success">
<a href="https://github.com/halfrost/LeetCode-Go/releases/" rel="nofollow"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/halfrost/LeetCode-Go/total?label=PDF%20downloads"></a>
<img src="https://img.shields.io/badge/Total%20Word%20Count-717961-success">
<a href="https://github.com/halfrost/LeetCode-Go/actions/workflows/deploy.yml" rel="nofollow"><img src="https://github.com/halfrost/LeetCode-Go/actions/workflows/deploy.yml/badge.svg?branch=master" alt="Deploy Status"></a>
<a href="https://github.com/halfrost/LeetCode-Go/actions/workflows/test.yml" rel="nofollow"><img src="https://github.com/halfrost/LeetCode-Go/actions/workflows/test.yml/badge.svg?branch=master" alt="Go Test Status"></a>
<a href="https://goreportcard.com/report/github.com/halfrost/LeetCode-Go" rel="nofollow"><img src="https://goreportcard.com/badge/github.com/halfrost/LeetCode-Go"></a>
<img src="https://img.shields.io/badge/runtime%20beats-100%25-success">
<a href="https://codecov.io/gh/halfrost/LeetCode-Go"><img src="https://codecov.io/gh/halfrost/LeetCode-Go/branch/master/graph/badge.svg" /></a>
<!--<img alt="GitHub go.mod Go version" src="https://img.shields.io/github/go-mod/go-version/halfrost/LeetCode-Go?color=26C2F0">-->
<img alt="Support Go version" src="https://img.shields.io/badge/Go-v1.15-26C2F0">
<img alt="Go Version" src="https://img.shields.io/github/go-mod/go-version/halfrost/LeetCode-Go?label=Go&color=26C2F0">
<img src="https://visitor-badge.laobi.icu/badge?page_id=halfrost.LeetCode-Go">
</p>

<p align='center'>
<a href="https://github.com/halfrost/leetcode-go/blob/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/halfrost/LeetCode-Go?label=License"></a>
<img src="https://img.shields.io/badge/License-CC-000000.svg">
<a href="https://github.com/halfrost/LeetCode-Go/blob/master/LICENSE"><img alt="Code License" src="https://img.shields.io/github/license/halfrost/LeetCode-Go?label=Code%20License"></a>
<img alt="Book License" src="https://img.shields.io/badge/Book%20License-CC-000000.svg">
<a href="https://leetcode.com/halfrost/"><img src="https://img.shields.io/badge/@halfrost-8751-yellow.svg">
<img src="https://img.shields.io/badge/language-Golang-26C2F0.svg">
<a href="https://halfrost.com"><img src="https://img.shields.io/badge/Blog-Halfrost--Field-80d4f9.svg?style=flat"></a>
<a href="http://weibo.com/halfrost"><img src="https://img.shields.io/badge/weibo-@halfrost-f974ce.svg?style=flat&colorA=f4292e"></a>
<a href="https://twitter.com/halffrost"><img src="https://img.shields.io/badge/twitter-@halffrost-F8E81C.svg?style=flat&colorA=009df2"></a>
<a href="https://www.zhihu.com/people/halfrost/activities"><img src="https://img.shields.io/badge/%E7%9F%A5%E4%B9%8E-@halfrost-fd6f32.svg?style=flat&colorA=0083ea"></a>
<img src="https://img.shields.io/badge/made%20with-=1-blue.svg">
<img src="https://img.shields.io/badge/made%20with-%E2%99%A5-blue.svg">
<a href="https://github.com/halfrost/LeetCode-Go/pulls"><img src="https://img.shields.io/badge/PR-Welcome-brightgreen.svg"></a>
</p>

Expand Down Expand Up @@ -3090,6 +3089,10 @@ Thank you for reading here. This is bonus. You can download my [《ACM-ICPC Algo



## License

The **code** in this repository (all Go solutions) is licensed under the [MIT License](https://github.com/halfrost/LeetCode-Go/blob/master/LICENSE). The **book content** of *LeetCode Cookbook* (the articles and illustrations served from the website) is licensed under a Creative Commons (CC) license. In short: feel free to reuse the code under MIT; the written/illustrated book content is shared under CC.

## ♥️ Thanks

Thanks for your Star!
Expand Down
79 changes: 54 additions & 25 deletions website/content/ChapterFour/pytool/WordCount.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,58 @@
from collections import defaultdict
#!/usr/bin/env python3
"""Count the total word count of the LeetCode-Go book.

Metric: Chinese characters (CJK ideographs) + English words, counted over the
authored Markdown only (the book content, the per-problem pages and the
top-level docs). Fenced / inline code blocks are stripped and the third-party
Hugo theme and code templates are excluded, so the number reflects written
prose rather than source code or numeric data.

The repo root is resolved from this file's location, so it can be run from any
directory:

python3 website/content/ChapterFour/pytool/WordCount.py
"""
import glob
import os
import re

HAN = re.compile(r"[一-鿿]") # CJK unified ideographs (汉字)
EN_WORD = re.compile(r"[A-Za-z]+") # English words
FENCED = re.compile(r"```.*?```", re.S) # ```fenced code blocks```
INLINE = re.compile(r"`[^`\n]*`") # `inline code`

# repo root = four levels up from website/content/ChapterFour/pytool/
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))

# Globs of authored Markdown, relative to the repo root.
GLOBS = [
"website/content/**/*.md", # the book《LeetCode Cookbook》
"leetcode/**/*.md", # per-problem pages
"note/*.md",
"*.md", # README and other top-level docs
]


def strip_code(text):
"""Remove fenced and inline code so only prose is counted."""
return INLINE.sub(" ", FENCED.sub(" ", text))


def count_words(text):
"""汉字 + English words, after stripping code."""
text = strip_code(text)
return len(HAN.findall(text)) + len(EN_WORD.findall(text))


def main():
files = sorted({f for g in GLOBS for f in glob.glob(os.path.join(ROOT, g), recursive=True)})
total = 0
for file_name in files:
with open(file_name, encoding="utf-8", errors="ignore") as fh:
total += count_words(fh.read())
print("files counted: {}".format(len(files)))
print("total word count (汉字 + English words, code excluded): {}".format(total))


def str_count2(str):
count_zh = count_dg = 0
for s in str:
# 中文字符范围
if '\u4e00' <= s <= '\u9fff':
count_zh += 1
if s.isdigit():
count_dg += 1
# print(count_zh + count_dg)
return count_zh + count_dg

current_working_dir = os.getcwd()
# print(f"current_working_dir: {current_working_dir}")

dir_names = glob.glob("*.md")
dir_names.sort()

word_count = 0
for file_name in dir_names:
with open(file_name, "r") as myfile:
codeContent = myfile.read()
print("当前读取文件: {}, 字数统计: {}".format(file_name, str_count2(codeContent)))
word_count += str_count2(codeContent)
print(word_count)
if __name__ == "__main__":
main()
Loading