跳转至

CFLMY-PPT自动生成记录文档003

前言

这是一个更新的版本,演示站点仍为:CFLMY-生成至美PPT

更新的配置

本次更新主要是将各部分进行了模块化,发生变化的部分分为:

main.js

const fs = require('fs');
const path = require('path');
const MarkdownIt = require('markdown-it');

//引入规则文件
const Head = require('./js/Head'); // 引入标题的定义文件
const Hr = require('./js/Hr'); // 引入分割线的定义文件
const Image = require('./js/Image'); // 引入图片的定义文件
const OrderList = require('./js/OrderList'); // 引入有序列表的定义文件
const BulletList = require('./js/BulletList'); // 引入无序列表的定义文件
const Code = require('./js/Code'); // 引入代码段的定义文件
const Link = require('./js/Link'); // 引入链接的定义文件
const Quote = require('./js/Quote'); // 引入引用的定义文件

const md = new MarkdownIt({
  html: true
});

// 读取头部和尾部文件
const headerFilePath = 'decorate/header.html'; // 头部文件路径
const footerFilePath = 'decorate/footer.html'; // 尾部文件路径
const markdownFilePath = 'index.md'; // Markdown 文件路径
const markdownDirPath = 'md'; // Markdown 文件夹路径
// 读取头部和尾部内容
const headerContent = fs.readFileSync(headerFilePath, 'utf-8');
const footerContent = fs.readFileSync(footerFilePath, 'utf-8');

// 读取 Markdown 文件
const markdownContent = fs.readFileSync(markdownFilePath, 'utf-8');

const markdownFiles = fs.readdirSync(markdownDirPath).filter(file => {
  return path.extname(file) === '.md'; // 仅处理 .md 文件
});

//从文件中读取定义的新规则
md.use(Head, { level: 1, wrapperTag: 'section' })
md.use(Hr);
md.use(Image, { defaultImage:'Assert/CFLMY.webp' });
md.use(OrderList);
md.use(BulletList);
md.use(Code);
md.use(Link);
md.use(Quote);


const htmlContent = md.render(markdownContent);

// 生成完整的 HTML
const fullHtml = headerContent + htmlContent + footerContent;

// 写入 HTML 文件
const outputFilePath = 'index.html'; // 你的输出 HTML 文件路径
fs.writeFileSync(outputFilePath, fullHtml, 'utf-8');

console.log(`Index HTML 文件已生成: ${outputFilePath}`);

// 遍历每个 Markdown 文件并生成对应的 HTML 文件
markdownFiles.forEach(markdownFile => {
  const markdownFilePath = path.join(markdownDirPath, markdownFile); // Markdown 文件的完整路径
  const markdownContent = fs.readFileSync(markdownFilePath, 'utf-8'); // 读取 Markdown 文件

  // 用于自定义渲染规则的代码
  // ... (保留原有的渲染规则) ...
  // 修改图片的默认路径
  md.use(Image, { defaultImage:'../Assert/CFLMY.webp' });


  const htmlContent = md.render(markdownContent); // 渲染 Markdown 内容为 HTML

  // 生成完整的 HTML
  const outputHtml = headerContent + htmlContent + footerContent;

  const outputFileName = path.basename(markdownFile, '.md') + '.html'; // 输出文件名
  const outputFilePath = path.join('html', outputFileName); // 输出 HTML 文件路径

  // 创建输出目录(如果不存在)
  if (!fs.existsSync('html')) {
      fs.mkdirSync('html');
  }

  // 写入 HTML 文件
  fs.writeFileSync(outputFilePath, outputHtml, 'utf-8');

  console.log(`md 目录下的HTML 文件已生成: ${outputFilePath}`);
});

Head.js

// Head.js
module.exports = function(md, options) {
    const opts = Object.assign({ level: 1, wrapperTag: 'section' }, options);  // 提供默认选项

    md.renderer.rules.heading_open = function (tokens, idx, options, env, self) {
      const level = tokens[idx].tag.slice(1); // 获取标题级别(h1, h2, h3...)

      if (parseInt(level) === opts.level) {
        return `\n<${opts.wrapperTag}>\n<h1>`;
      }

      return self.renderToken(tokens, idx, options); // 默认行为
    };
  };

Hr.js

// Hr.js
module.exports = function(md) {
    md.renderer.rules.hr = function () {
      return ' <hr> \n </div> \n </section> \n'; // 自定义分割线样式
    };
  };

Image.js

//Image.js
module.exports = function(md, options) {
    const defaultImage = options.defaultImage || 'Assert/CFLMY.webp'; // 默认值

    md.renderer.rules.image = function (tokens, idx, options, env, self) {
      const token = tokens[idx];
      const alt = token.content; // 获取 alt 文本
      const src = token.attrs[token.attrIndex('src')][1]; // 获取 src 属性

      // 定义一个映射对象用于存储不同 alt 文本的处理信息
      const backgroundStyles = {
        'BackGround': '',                // 不添加额外类
        'BackGround-aligncenter': ' aligncenter', // 添加 aligncenter 类
        // 你可以添加更多的 alt 文本和对应样式
      };

      // 获取对应样式后缀
      const className = backgroundStyles[alt]; // 如果 alt 不在映射中,className 为 undefined

      // 默认情况下,使用缺省的背景图像
      const backgroundImage = src ? `url('${src}')` : `url('${defaultImage}')`;

      // 只要 alt 文本在映射中存在,就返回相应的 HTML
      if (className !== undefined) {
          return `<span class="background" style="background-image:${backgroundImage};"></span>\n<div class="wrap${className}">`;
      }

      // 默认行为
      return self.renderToken(tokens, idx, options);
    };
  };

OrderList.js

//OrderedList.js
module.exports = function(md) {
    md.renderer.rules.ordered_list_open = function (tokens, idx, options, env, self) {
      // 在有序列表前添加内容
      return `<div class="bg-white shadow">
                  <ul class="flexblock reasons">`; // 可以自定义前置内容
    };

    md.renderer.rules.ordered_list_close = function (tokens, idx, options, env, self) {
      // 在有序列表后添加内容
      return `</ul>
                </div>`; // 可以自定义后置内容
    };
  };

BulletList.js

//BulletList.js
module.exports = function(md) {
  function WhetherGallery(tokens, idx) {
    // 遍历从当前列表开始的所有 token,直到列表结束
    for (let i = idx + 1; i < tokens.length; i++) {
      const token = tokens[i];
      if (token.content) {
        // 如果找到列表项内容,检查是否以 "[IMG-content-description]" 开头
        content = token.content;
        const match1 = content.match(/^\s*\[IMG-.*/);
        if (match1) {
          return true; // 列表中包含以 "[IMG-content-description]" 开头的项
      }
      } else if (token.type === 'list_item_close') {
        // 遇到列表项结束,继续查找下一个列表项
        continue;
      } else if (token.type === 'bullet_list_close') {
        // 遇到列表结束,停止查找
        break;
      }
    }
    return false; // 列表中不包含以 "+" 开头的项
  }

  md.renderer.rules.bullet_list_open = function(tokens, idx, options, env, self) {
    const isPlusList = WhetherGallery(tokens, idx);
    return isPlusList ? `<ul class="flexblock gallery">` : `<ul class="flexblock features">`;
  };

  md.renderer.rules.bullet_list_close = function() {
    return `</ul>`;
  };
};

Code.js

//Code.js
module.exports = function(md) {
    md.renderer.rules.fenced_code_open = function(tokens, idx, options, env, self) {
      // 在代码块前添加内容
      return `<div class="column">
                  <pre>`;
    };

    md.renderer.rules.fenced_code_close = function(tokens, idx, options, env, self) {
      // 在代码块后添加内容
      return `</pre>
                </div>`;
    };
  };

Link.js

//Link.js
module.exports = function(md) {
    md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
      const token = tokens[idx];
      const alt = tokens[idx + 1].content; // 获取链接文本
      const href = tokens[idx].attrs[token.attrIndex('href')][1];

      // 使用正则表达式给包含 "IMG-" 的 alt 文本设置类名
      const match1 = alt.match(/^(IMG)-(.*?)-(.*)$/);

      if (match1) {
        const prefix = match1[1]; // "IMG"
        const imgHref = match1[2]; // "图片链接"
        const description = match1[3]; // "描述"
        tokens[idx + 1].content = description;
        token.customMatch = true; // 添加一个自定义属性到 open token

        return `<a href="${href}">
                      <figure>
                        <img alt="" src="${imgHref}">
                        <figcaption>
                          <h2>
                    `;
      }

      // 默认行为
      return self.renderToken(tokens, idx, options);
    };

    md.renderer.rules.link_close = function (tokens, idx, options, env, self) {
      const token = tokens[idx - 1]; // 获取对应的 open token
      if (token.customMatch) { // 检查是否存在 customMatch 属性
        delete token.customMatch; // 清除 customMatch 属性
        return `</h2>
                    </figcaption>
                  </figure>
                </a>`;
      }

      // 默认关闭标签行为
      return self.renderToken(tokens, idx, options);
    };
  };

Quote.js

//Quote.js
module.exports = function(md) {
  md.renderer.rules.blockquote_open = function (tokens, idx, options, env, self) {
    // 返回定义好的开头HTML,可以为引用添加特定的类或样式
    return '<ul class="flexblock gallery"><li>';
  };

  md.renderer.rules.blockquote_close = function (tokens, idx, options, env, self) {
    // 返回引用结束的HTML
    return '</li></ul>';
  };

};

更新内容

  1. 模块化各部分
  2. 修改无序列表的生成逻辑,使得当无序列表的首个引导为[IMG-时自动替换为gallery选项,从而较好的保持原有的样式的基础上,支持了插入图片式链接的需求。
  3. 修改标题的逻辑,便于进行拓展和更新
  4. 修改引用的格式
  5. 修改Link部分的匹配,便于后续不断增加更多的链接有关语法。

后记

0.0.3版本注重与模块化,方便了调试和修改。