Merge pull request #53 from sudo-Harshk/fix/stats-regex
fix(stats): implement regex for sentences, lists, and tables
This commit is contained in:
commit
d7c50eaac0
|
|
@ -2962,6 +2962,15 @@ function noteApp() {
|
||||||
// Paragraph count
|
// Paragraph count
|
||||||
const paragraphs = content.split('\n\n').filter(p => p.trim()).length;
|
const paragraphs = content.split('\n\n').filter(p => p.trim()).length;
|
||||||
|
|
||||||
|
// Sentences: punctuation [.!?]+ followed by space or end-of-string
|
||||||
|
const sentences = (content.match(/[.!?]+(?:\s|$)/g) || []).length;
|
||||||
|
|
||||||
|
// List items: lines starting with -, *, + or a number (e.g. 1., 10.), excluding tasks [-]
|
||||||
|
const listItems = (content.match(/^\s*(?:[-*+]|\d+\.)\s+(?!\[)/gm) || []).length;
|
||||||
|
|
||||||
|
// Tables: separator rows containing both '|' and '---'
|
||||||
|
const tables = (content.match(/^(?=.*\|)(?=.*---).*$/gm) || []).length;
|
||||||
|
|
||||||
// Link count
|
// Link count
|
||||||
const linkMatches = content.match(/\[([^\]]+)\]\(([^\)]+)\)/g) || [];
|
const linkMatches = content.match(/\[([^\]]+)\]\(([^\)]+)\)/g) || [];
|
||||||
const links = linkMatches.length;
|
const links = linkMatches.length;
|
||||||
|
|
@ -2990,11 +2999,14 @@ function noteApp() {
|
||||||
|
|
||||||
this.noteStats = {
|
this.noteStats = {
|
||||||
words,
|
words,
|
||||||
|
sentences,
|
||||||
characters: chars,
|
characters: chars,
|
||||||
total_characters: totalChars,
|
total_characters: totalChars,
|
||||||
reading_time_minutes: readingTime,
|
reading_time_minutes: readingTime,
|
||||||
lines,
|
lines,
|
||||||
paragraphs,
|
paragraphs,
|
||||||
|
list_items: listItems,
|
||||||
|
tables,
|
||||||
links,
|
links,
|
||||||
internal_links: internalLinks,
|
internal_links: internalLinks,
|
||||||
external_links: links - internalLinks,
|
external_links: links - internalLinks,
|
||||||
|
|
|
||||||
|
|
@ -1567,6 +1567,24 @@
|
||||||
<div class="font-semibold" style="color: var(--text-primary);" x-text="noteStats ? noteStats.lines.toLocaleString() : '0'"></div>
|
<div class="font-semibold" style="color: var(--text-primary);" x-text="noteStats ? noteStats.lines.toLocaleString() : '0'"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Sentences -->
|
||||||
|
<div>
|
||||||
|
<div class="text-xs" style="color: var(--text-tertiary);">Sentences</div>
|
||||||
|
<div class="font-semibold" style="color: var(--text-primary);" x-text="noteStats ? noteStats.sentences.toLocaleString() : '0'"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Lists -->
|
||||||
|
<div>
|
||||||
|
<div class="text-xs" style="color: var(--text-tertiary);">Lists</div>
|
||||||
|
<div class="font-semibold" style="color: var(--text-primary);" x-text="noteStats ? noteStats.list_items.toLocaleString() : '0'"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tables -->
|
||||||
|
<div>
|
||||||
|
<div class="text-xs" style="color: var(--text-tertiary);">Tables</div>
|
||||||
|
<div class="font-semibold" style="color: var(--text-primary);" x-text="noteStats ? noteStats.tables.toLocaleString() : '0'"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Links -->
|
<!-- Links -->
|
||||||
<template x-if="noteStats && noteStats.links > 0">
|
<template x-if="noteStats && noteStats.links > 0">
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,19 @@ class Plugin:
|
||||||
# Paragraph count (blocks separated by blank lines)
|
# Paragraph count (blocks separated by blank lines)
|
||||||
paragraphs = len([p for p in content.split('\n\n') if p.strip()])
|
paragraphs = len([p for p in content.split('\n\n') if p.strip()])
|
||||||
|
|
||||||
|
# Sentence count: punctuation [.!?]+ followed by space or end-of-string
|
||||||
|
sentences = len(re.findall(r'[.!?]+(?:\s|$)', content))
|
||||||
|
|
||||||
|
# List items: lines starting with -, *, + or a number (e.g. 1., 10.), excluding tasks [-]
|
||||||
|
list_items = len(
|
||||||
|
re.findall(r'^\s*(?:[-*+]|\d+\.)\s+(?!\[)', content, re.MULTILINE)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Tables: count separator rows containing both '|' and '---'
|
||||||
|
tables = len(
|
||||||
|
re.findall(r'^(?=.*\|)(?=.*---).*$', content, re.MULTILINE)
|
||||||
|
)
|
||||||
|
|
||||||
# Markdown link count
|
# Markdown link count
|
||||||
links = len(re.findall(r'\[([^\]]+)\]\(([^\)]+)\)', content))
|
links = len(re.findall(r'\[([^\]]+)\]\(([^\)]+)\)', content))
|
||||||
|
|
||||||
|
|
@ -71,11 +84,14 @@ class Plugin:
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'words': words,
|
'words': words,
|
||||||
|
'sentences': sentences,
|
||||||
'characters': chars,
|
'characters': chars,
|
||||||
'total_characters': total_chars,
|
'total_characters': total_chars,
|
||||||
'reading_time_minutes': reading_time,
|
'reading_time_minutes': reading_time,
|
||||||
'lines': lines,
|
'lines': lines,
|
||||||
'paragraphs': paragraphs,
|
'paragraphs': paragraphs,
|
||||||
|
'list_items': list_items,
|
||||||
|
'tables': tables,
|
||||||
'links': links,
|
'links': links,
|
||||||
'internal_links': internal_links,
|
'internal_links': internal_links,
|
||||||
'external_links': links - internal_links,
|
'external_links': links - internal_links,
|
||||||
|
|
@ -129,7 +145,14 @@ class Plugin:
|
||||||
|
|
||||||
# Log key statistics
|
# Log key statistics
|
||||||
print(f"📊 {note_path}:")
|
print(f"📊 {note_path}:")
|
||||||
print(f" {stats['words']:,} words | {stats['reading_time_minutes']}m read | {stats['lines']:,} lines")
|
print(
|
||||||
|
f" {stats['words']:,} words | "
|
||||||
|
f"{stats['sentences']:,} sentences | "
|
||||||
|
f"{stats['reading_time_minutes']}m read | "
|
||||||
|
f"{stats['lines']:,} lines | "
|
||||||
|
f"{stats['list_items']:,} lists | "
|
||||||
|
f"{stats['tables']:,} tables"
|
||||||
|
)
|
||||||
|
|
||||||
if stats['links'] > 0:
|
if stats['links'] > 0:
|
||||||
print(f" {stats['links']} links ({stats['internal_links']} internal)")
|
print(f" {stats['links']} links ({stats['internal_links']} internal)")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue