60 lines
2.2 KiB
JavaScript
60 lines
2.2 KiB
JavaScript
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);
|
||
}
|