From 293cebd4f609fa82795b02e03463d15b7da7acc4 Mon Sep 17 00:00:00 2001 From: Menci Date: Sat, 23 Mar 2019 21:18:12 +0800 Subject: [PATCH] Update README and add migrates --- README.en.md | 2 + README.md | 2 + migrates/html-table-merge-cell-to-md.js | 127 ++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100755 migrates/html-table-merge-cell-to-md.js diff --git a/README.en.md b/README.en.md index 8e1d41e..4c3abcc 100644 --- a/README.en.md +++ b/README.en.md @@ -44,3 +44,5 @@ Who upgraded from a commit BEFORE [d8be150fc6b8c43af61c5e4aca4fc0fe0445aef3](htt ```sql ALTER TABLE `user` ADD `prefer_formatted_code` TINYINT(1) NOT NULL DEFAULT 1 AFTER `public_email`; ``` + +Who upgraded from a commit BEFORE [c192e8001ac81cab132ae033b39f09a094587633](https://github.com/syzoj/syzoj/commit/c192e8001ac81cab132ae033b39f09a094587633) (Mar 23, 2019) **MUST** install `redis-server` and [pygments](http://pygments.org/) on the web server. Markdown contents may be broken by switching to new renderer, [migrates/html-table-merge-cell-to-md.js](migrates/html-table-merge-cell-to-md.js) may help the migration。 diff --git a/README.md b/README.md index a41c390..a0405a4 100644 --- a/README.md +++ b/README.md @@ -44,3 +44,5 @@ ALTER TABLE `problem` ADD `publicize_time` DATETIME NOT NULL DEFAULT CURRENT_TIM ```sql ALTER TABLE `user` ADD `prefer_formatted_code` TINYINT(1) NOT NULL DEFAULT 1 AFTER `public_email`; ``` + +从该 commit [c192e8001ac81cab132ae033b39f09a094587633](https://github.com/syzoj/syzoj/commit/c192e8001ac81cab132ae033b39f09a094587633)(2019 年 3 月 23 日)前更新的用户**必须**在网站服务器上安装 `redis-server` 与 [pygments](http://pygments.org/)。旧的 Markdown 内容可能因切换到新渲染器被破坏,[migrates/html-table-merge-cell-to-md.js](migrates/html-table-merge-cell-to-md.js) 可能对迁移有所帮助。 diff --git a/migrates/html-table-merge-cell-to-md.js b/migrates/html-table-merge-cell-to-md.js new file mode 100755 index 0000000..475fe1b --- /dev/null +++ b/migrates/html-table-merge-cell-to-md.js @@ -0,0 +1,127 @@ +/* + * This script will help migrate from the old marked-based markdown renderer + * to the new markdown-it based (syzoj-renderer). + * + * The later doesn't support inline markdown inside HTML blocks. But in + * LibreOJ that's widely used in problem's limits' cell-merged table displaying + * displaying. So TeX maths inside are broken. + */ + +const cheerio = require('cheerio'); + +function processMarkdown(text) { + return text.replace(/()/gi, (match, offset, string) => { + const $ = cheerio.load(match, { decodeEntities: false }), + table = $('table'); + + let defaultAlign = '-'; + if (table.hasClass('center')) defaultAlign = ':-:'; + else if (table.hasClass('left')) defaultAlign = ':-'; + else if (table.hasClass('right')) defaultAlign = '-:'; + + let columnCount = 0; + const columnAlign = []; + table.find('th').each((i, th) => { + const count = parseInt($(th).attr('colspan')) || 1; + columnCount += count; + + const style = ($(th).attr('style') || '').split(' ').join('').toLowerCase(); + if (style.includes('text-align:center')) columnAlign.push(':-:'); + else if (style.includes('text-align:left')) columnAlign.push(':-'); + else if (style.includes('text-align:right')) columnAlign.push('-:'); + else columnAlign.push(defaultAlign); + }); + + const rowCount = table.find('tr').length; + + function escape(s) { + return ` ${s.trim().split('|').join('\\|')} `; + } + + const matrix = Array(rowCount).fill(null).map(() => []); + table.find('tr').each((i, tr) => { + const cells = $(tr).find('th, td'); + + let columnIndex = 0, resColumnIndex = 0; + cells.each((j, td) => { + while (typeof matrix[i][resColumnIndex] !== 'undefined') resColumnIndex++; + + if (columnIndex >= columnCount) return false; + if (resColumnIndex >= columnCount) return false; + + const colspan = parseInt($(td).attr('colspan')) || 1, + rowspan = parseInt($(td).attr('rowspan')) || 1, + content = $(td).html(); + + for (let cntRow = 0; cntRow < rowspan; cntRow++) { + for (let cntCol = 0; cntCol < colspan; cntCol++) { + if (i + cntRow < rowCount && resColumnIndex + cntCol < columnCount) { + matrix[i + cntRow][resColumnIndex + cntCol] = escape(content); + } + } + } + + resColumnIndex += colspan; + }); + }); + + const code = [matrix[0], columnAlign, ...matrix.slice(1)].map(row => `|${row.join('|')}|`).join('\n'); + + return `\n\n${code}\n\n\n\n`; + }); +} + +// Load syzoj. +process.chdir(__dirname + '/..'); +require('..'); + +const modelFields = { + problem: [ + 'description', + 'input_format', + 'output_format', + 'example', + 'limit_and_hint' + ], + contest: [ + 'information', + 'problems' + ], + article: [ + 'content' + ], + 'article-comment': [ + 'content' + ] +}; + +const fn = async () => { + for (const model in modelFields) { + const modelObject = syzoj.model(model); + const allData = await modelObject.all(); + + let cnt = 0, tot = allData.length; + for (const obj of allData) { + console.log(`${model}: ${++cnt}/${tot}`); + + let modified = false; + + for (field of modelFields[model]) { + const processed = processMarkdown(obj[field]); + if (processed != obj[field]) { + obj[field] = processed; + modified = true; + } + } + + if (modified) { + await obj.save(); + } + } + } + + process.exit(); +}; + +// NOTE: Uncomment to run. +// fn();