本周总览

const dailyFolder = "Z-Essays/Daily";
 
// 取今天所在周的周一
const today = dv.date("today");
const monday = today.minus({ days: today.weekday - 1 });
 
// 周一到周五
const days = Array.from({ length: 5 }, (_, i) => monday.plus({ days: i }));
 
function fileNameOfDay(d) {
  return d.toFormat("yyyy-MM-dd");
}
 
function fileLinkOfDay(d) {
  const name = fileNameOfDay(d);
  const page = dv.page(`${dailyFolder}/${name}`);
  return page ? page.file.link : name;
}
 
// 从 markdown 原文里提取某个标题下面的内容
async function extractSection(path, headingText) {
  const content = await dv.io.load(path);
  if (!content) return "";
 
  const lines = content.split("\n");
 
  let start = -1;
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i].trim();
    // 只要是标题行,并且包含关键词就算匹配
    if (/^#{1,6}\s+/.test(line) && line.includes(headingText)) {
      start = i + 1;
      break;
    }
  }
 
  if (start === -1) return "";
 
  let end = lines.length;
  for (let i = start; i < lines.length; i++) {
    if (/^#{1,6}\s+/.test(lines[i].trim())) {
      end = i;
      break;
    }
  }
 
  return lines.slice(start, end).join("\n").trim();
}
 
// 提取任务/列表并转成简短 HTML
function toCompactHtml(md) {
  if (!md || md === "—") return "—";
  return md
    .split("\n")
    .filter(x => x.trim())
    .map(x => x
      .replace(/^- \[x\] /i, "✅ ")
      .replace(/^- \[ \] /i, "⬜ ")
      .replace(/^- /, "• "))
    .join("<br>");
}
 
const row = [];
 
// 周一到周五内容:优先取“今日进展”
for (const d of days) {
  const name = fileNameOfDay(d);
  const page = dv.page(`${dailyFolder}/${name}`);
 
  if (!page) {
    row.push(`**${name}**<br>—`);
    continue;
  }
 
  const section = await extractSection(page.file.path, "今日TODO");
  row.push(`${page.file.link}\n${section || "—"}`);
}
 
// 第六列:当前周报页内容
const allDone = [];
 
for (const d of days) {
  const name = fileNameOfDay(d);
  const page = dv.page(`${dailyFolder}/${name}`);
 
  if (!page) continue;
 
  const section = await extractSection(page.file.path, "今日TODO");
  if (!section) continue;
 
  const done = section
    .split("\n")
    .map(x => x.trim())
    .filter(x => /^- \[[xX]\]\s+/.test(x))
    .map(x => x.replace(/^- \[[xX]\]\s+/, "").trim());
 
  allDone.push(...done);
}
 
// ✅ 关键:保证永远有字符串输出
let weeklySummary = "—";
 
if (allDone.length > 0) {
  const uniqueDone = [...new Set(allDone)];
  weeklySummary = uniqueDone.length  
        ? uniqueDone.map(x => `• ${x}`).join("<br>")  
        : "—";
}
 
// 👇 强制保证不是 undefined / 空
row.push(weeklySummary || "—");
 
const headers = ["周一", "周二", "周三", "周四", "周五", "周报"];  
  
for (let i = 0; i < headers.length; i++) {  
dv.paragraph(`### ${headers[i]}\n${row[i]}`);  
}

本周待做

const dailyFolder = "Z-Essays/Daily";
const today = dv.date("today");
 
// 时间范围:本周一 ~ 本周日
const thisMonday = today.minus({ days: today.weekday - 1 });
const thisSunday = thisMonday.plus({ days: 6 });
 
const pages = dv.pages(`"${dailyFolder}"`)
  .where(p => p.file.day &&
    p.file.day.toMillis() >= thisMonday.toMillis() &&
    p.file.day.toMillis() <= thisSunday.toMillis());
 
function normalizeTaskText(text) {
  return (text || "")
    .trim()
    .replace(/\s+/g, " ")
    .toLowerCase();
}
 
// key => Map<dayMs, record>
// 同一天同一任务出现多次时,completed 状态优先
const taskDayMap = new Map();
 
for (const page of pages) {
  const dayMs = page.file.day.toMillis();
  for (const task of page.file.tasks) {
    const raw = (task.text || "").trim();
    if (!raw) continue;
 
    const key = normalizeTaskText(raw);
    if (!taskDayMap.has(key)) taskDayMap.set(key, new Map());
 
    const dayBucket = taskDayMap.get(key);
    const existing = dayBucket.get(dayMs);
 
    if (!existing || (!existing.completed && task.completed)) {
      dayBucket.set(dayMs, {
        text: raw,
        completed: !!task.completed,
        day: page.file.day,
        file: page.file.link
      });
    }
  }
}
 
// 每个任务只看最新那天的状态
const latestPending = [];
 
for (const [key, dayBucket] of taskDayMap.entries()) {
  const records = [...dayBucket.values()]
    .sort((a, b) => b.day.toMillis() - a.day.toMillis());
 
  const latest = records[0];
 
  // 最新那天已完成 → 不显示
  if (latest.completed) continue;
 
  latestPending.push(latest);
}
 
latestPending.sort((a, b) => b.day.toMillis() - a.day.toMillis());
 
if (latestPending.length === 0) {
  dv.paragraph("—");
} else {
  for (const item of latestPending) {
    dv.paragraph(`- [ ] ${item.text}  \n  ↳ ${item.day.toFormat("yyyy-MM-dd")} ${item.file}`);
  }
}

上周回顾

const dailyFolder = "Z-Essays/Daily";
 
// 取上周的周一
const today = dv.date("today");
const thisMonday = today.minus({ days: today.weekday - 1 });
const monday = thisMonday.minus({ days: 7 });
 
// 上周周一到周五
const days = Array.from({ length: 5 }, (_, i) => monday.plus({ days: i }));
 
function fileNameOfDay(d) {
  return d.toFormat("yyyy-MM-dd");
}
 
function fileLinkOfDay(d) {
  const name = fileNameOfDay(d);
  const page = dv.page(`${dailyFolder}/${name}`);
  return page ? page.file.link : name;
}
 
// 从 markdown 原文里提取某个标题下面的内容
async function extractSection(path, headingText) {
  const content = await dv.io.load(path);
  if (!content) return "";
 
  const lines = content.split("\n");
 
  let start = -1;
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i].trim();
    // 只要是标题行,并且包含关键词就算匹配
    if (/^#{1,6}\s+/.test(line) && line.includes(headingText)) {
      start = i + 1;
      break;
    }
  }
 
  if (start === -1) return "";
 
  let end = lines.length;
  for (let i = start; i < lines.length; i++) {
    if (/^#{1,6}\s+/.test(lines[i].trim())) {
      end = i;
      break;
    }
  }
 
  return lines.slice(start, end).join("\n").trim();
}
 
// 提取任务/列表并转成简短 HTML
function toCompactHtml(md) {
  if (!md || md === "—") return "—";
  return md
    .split("\n")
    .filter(x => x.trim())
    .map(x => x
      .replace(/^- \[x\] /i, "✅ ")
      .replace(/^- \[ \] /i, "⬜ ")
      .replace(/^- /, "• "))
    .join("<br>");
}
 
const row = [];
 
// 上周周一到周五内容
for (const d of days) {
  const name = fileNameOfDay(d);
  const page = dv.page(`${dailyFolder}/${name}`);
 
  if (!page) {
    row.push(`**${name}**<br>—`);
    continue;
  }
 
  const section = await extractSection(page.file.path, "今日TODO");
  row.push(`${page.file.link}\n${section || "—"}`);
}
 
// 第六列:上周完成汇总
const allDone = [];
 
for (const d of days) {
  const name = fileNameOfDay(d);
  const page = dv.page(`${dailyFolder}/${name}`);
 
  if (!page) continue;
 
  const section = await extractSection(page.file.path, "今日TODO");
  if (!section) continue;
 
  const done = section
    .split("\n")
    .map(x => x.trim())
    .filter(x => /^- \[[xX]\]\s+/.test(x))
    .map(x => x.replace(/^- \[[xX]\]\s+/, "").trim());
 
  allDone.push(...done);
}
 
// 保证永远有字符串输出
let weeklySummary = "—";
 
if (allDone.length > 0) {
  const uniqueDone = [...new Set(allDone)];
  weeklySummary = uniqueDone.length
    ? uniqueDone.map(x => `• ${x}`).join("<br>")
    : "—";
}
 
row.push(weeklySummary || "—");
 
const headers = ["周一", "周二", "周三", "周四", "周五", "周报"];
 
for (let i = 0; i < headers.length; i++) {
  dv.paragraph(`### ${headers[i]}\n${row[i]}`);
}