initial commit
This commit is contained in:
59
server/calendar.js
Normal file
59
server/calendar.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import { readDocx } from "./parser.js";
|
||||
|
||||
const toIso = (d, m, y) =>
|
||||
`${y}-${m.padStart(2, "0")}-${d.padStart(2, "0")}`;
|
||||
const time = (h, m) => `${h.padStart(2, "0")}:${m}`;
|
||||
|
||||
// "Расписание белых и зеленых недель.docx": pairs of cells "номер | дд.мм.гггг-дд.мм.гггг".
|
||||
export function parseWeeksDocx(buffer) {
|
||||
const { tables } = readDocx(buffer);
|
||||
const weeks = [];
|
||||
for (const { rows } of tables) {
|
||||
const header = rows[0] || [];
|
||||
const colorOf = (col) => {
|
||||
const label = header.find((c) => c.col === col)?.text.toLowerCase() || "";
|
||||
return /зел[её]н/.test(label) ? "green" : /бел/.test(label) ? "white" : null;
|
||||
};
|
||||
for (const row of rows)
|
||||
row.forEach((cell, i) => {
|
||||
const range = cell.text.match(
|
||||
/(\d{1,2})\.(\d{1,2})\.(\d{4})\s*[-–]\s*(\d{1,2})\.(\d{1,2})\.(\d{4})/,
|
||||
);
|
||||
const n = Number(row[i - 1]?.text.match(/^\d{1,2}$/)?.[0]);
|
||||
if (!range || !n) return;
|
||||
weeks.push({
|
||||
n,
|
||||
start: toIso(range[1], range[2], range[3]),
|
||||
end: toIso(range[4], range[5], range[6]),
|
||||
color: colorOf(cell.col) || (n % 2 ? "white" : "green"),
|
||||
});
|
||||
});
|
||||
}
|
||||
weeks.sort((a, b) => a.start.localeCompare(b.start));
|
||||
if (!weeks.length)
|
||||
throw new Error("Таблица недель не распознана.");
|
||||
return weeks;
|
||||
}
|
||||
|
||||
// "Расписание звонков.docx": "1 пара | 8.30 – 9.10 9.15 – 9.55".
|
||||
export function parseBellsDocx(buffer) {
|
||||
const { tables } = readDocx(buffer);
|
||||
const bells = [];
|
||||
for (const { rows } of tables)
|
||||
for (const row of rows) {
|
||||
const pair = Number(row[0]?.text.match(/^(\d)\s*пара/i)?.[1]);
|
||||
const times = [
|
||||
...row
|
||||
.slice(1)
|
||||
.map((c) => c.text)
|
||||
.join(" ")
|
||||
.matchAll(/([0-2]?\d)[.:]([0-5]\d)/g),
|
||||
].map((m) => time(m[1], m[2]));
|
||||
if (!pair || times.length < 2) continue;
|
||||
const halves = [];
|
||||
for (let i = 0; i + 1 < times.length; i += 2)
|
||||
halves.push([times[i], times[i + 1]]);
|
||||
bells.push({ pair, start: times[0], end: times.at(-1), halves });
|
||||
}
|
||||
return bells.sort((a, b) => a.pair - b.pair);
|
||||
}
|
||||
Reference in New Issue
Block a user