48 Commits

Author SHA1 Message Date
renovate[bot]
59da2d1ff0 fix(deps): update dependency react-router-dom to v7 2024-11-22 08:32:10 +00:00
jaywcjlove
8991adcd15 ci: update workflows config. 2024-08-05 00:58:24 +08:00
jaywcjlove
1b2e3b534d released v2.4.0 2024-08-05 00:56:10 +08:00
jaywcjlove
d85368cb4f type: fix type error. 2024-08-05 00:44:13 +08:00
jaywcjlove
8b4194f5ae ci: update workflows config. 2024-08-05 00:03:05 +08:00
renovate[bot]
ab3423a697 fix(deps): update dependency rehype-prism-plus to v2 (#47)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 00:02:54 +08:00
renovate[bot]
504259b862 fix(deps): update remark (#48)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 00:02:27 +08:00
renovate[bot]
b05d90e15b fix(deps): update dependency rehype-stringify to v10 (#31)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 00:00:33 +08:00
renovate[bot]
f6e71388f1 fix(deps): update dependency rehype-ignore to v2 (#46)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 00:00:14 +08:00
renovate[bot]
1c9a7a8668 fix(deps): update dependency rehype-raw to v7 (#30)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-04 23:59:33 +08:00
renovate[bot]
314f47f8af fix(deps): update dependency rehype-attr to v3 (#36)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-04 23:59:14 +08:00
renovate[bot]
be06f694a5 fix(deps): update dependency unified to v11 (#29)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-04 23:58:31 +08:00
renovate[bot]
c23ada95ff chore(deps): update dependency tsbb to ~4.4.0 (#45)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-04 23:37:41 +08:00
renovate[bot]
2632cb1938 fix(deps): update dependency @uiw/react-markdown-editor to v6 (#43)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-04 23:36:07 +08:00
jaywcjlove
77616468a4 fix: fix copy issue. #44 2024-08-04 23:34:33 +08:00
jaywcjlove
41eb86cd2b ci: update workflows config. 2024-06-29 22:20:31 +08:00
jaywcjlove
5fe5ddfa61 ci: update workflow config. 2024-04-03 16:34:12 +08:00
renovate[bot]
82cc2a3df4 chore(deps): update lerna monorepo to v8 (#40)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-03 16:26:12 +08:00
renovate[bot]
b5596d76b6 fix(deps): update dependency styled-components to ~6.1.0 (#39)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-03 16:25:25 +08:00
renovate[bot]
d2c2746420 chore(deps): update dependency tsbb to ~4.2.0 (#34)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-03 16:17:38 +08:00
jaywcjlove
ef1ed54be7 chore: add sponsor badge. 2023-11-25 21:04:59 +08:00
jaywcjlove
e3a3cf5ff6 chore: update .github/workflows/ci.yml 2023-08-25 11:51:58 +08:00
jaywcjlove
4f4ad71d09 chore: update .github/workflows/ci.yml 2023-08-25 11:29:03 +08:00
jaywcjlove
3b32e76f65 style: modify theme style. 2023-08-25 11:28:47 +08:00
jaywcjlove
056b792519 chore: update .github/workflows/ci.yml 2023-08-25 11:14:20 +08:00
jaywcjlove
de98442b3c chore: update workflows config. 2023-08-25 00:03:40 +08:00
jaywcjlove
8bf24877bf fix: Fix {name} does not correspond to supportd language and throw an error. 2023-08-22 17:44:56 +08:00
jaywcjlove
ad546bfb6c chore(deps): update dependencies. 2023-08-22 17:42:24 +08:00
renovate[bot]
bac929d894 chore(deps): update dependency tsbb to ~4.1.0 (#20)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-04 15:58:05 +08:00
jaywcjlove
ab1c043931 chore(deps): update dependency tsbb to v4 #20
https://github.com/jaywcjlove/tsbb/issues/439
2023-03-30 21:51:54 +08:00
jaywcjlove
5afb09a715 style: modify underscore themes. 2022-10-24 23:00:59 +08:00
jaywcjlove
df79dcf694 chore(deps): Update @uiw/react-markdown-editor dependency to ^5.10.0 2022-09-22 14:15:54 +08:00
jaywcjlove
33a60420a4 released v2.3.3 2022-09-17 11:32:18 +08:00
jaywcjlove
c7dba6d5de website: update commamnd style. 2022-09-17 11:31:43 +08:00
jaywcjlove
ed596a7403 chore: update workflows config. 2022-09-13 12:40:35 +08:00
jaywcjlove
7f28e6ada1 released v2.3.2 2022-09-13 11:29:17 +08:00
renovate[bot]
df10f96a65 chore(deps): update dependency electron to v20 (#8) 2022-09-13 11:01:04 +08:00
jaywcjlove
02cb33cfcd released v2.3.1 2022-09-12 17:57:06 +08:00
jaywcjlove
13a96916d7 doc: Update README.md 2022-09-12 17:56:27 +08:00
jaywcjlove
245d54e511 doc: Update README.md 2022-09-12 17:55:42 +08:00
jaywcjlove
06e216aa22 doc: Update README.md 2022-09-12 17:54:26 +08:00
jaywcjlove
a50acf3888 chore: update workflows config. 2022-09-12 17:53:51 +08:00
jaywcjlove
195d2ce8d0 chore: update workflows config. 2022-09-12 17:51:09 +08:00
renovate[bot]
9adcd7eaa7 chore(deps): update dependency lerna to v5.5.1 (#9) 2022-09-12 17:40:10 +08:00
jaywcjlove
193ec20a22 released v2.3.0 2022-09-06 00:38:15 +08:00
jaywcjlove
8f62d41020 feat: add color palette. 2022-09-06 00:08:46 +08:00
jaywcjlove
8720638f9d style: modify theme style. 2022-09-06 00:08:46 +08:00
renovate[bot]
8d33e4dab2 chore(deps): update dependency electron-builder to v23.3.3 (#6) 2022-09-05 10:47:03 +08:00
29 changed files with 460 additions and 296 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
ko_fi: jaywcjlove
buy_me_a_coffee: jaywcjlove
custom: ["https://www.paypal.me/kennyiseeyou", "https://jaywcjlove.github.io/#/sponsor"]

View File

@@ -6,17 +6,18 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: 16 node-version: 20
registry-url: 'https://registry.npmjs.org'
- run: npm install - run: npm install
- run: npm run build - run: npm run build
- run: npm run doc - run: npm run doc
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
with: with:
name: webiste name: webiste
path: | path: |
@@ -40,7 +41,7 @@ jobs:
uses: jaywcjlove/changelog-generator@main uses: jaywcjlove/changelog-generator@main
- name: Deploy - name: Deploy
uses: peaceiris/actions-gh-pages@v3 uses: peaceiris/actions-gh-pages@v4
with: with:
commit_message: ${{ github.event.head_commit.message }} ${{steps.tag_version.outputs.tag}} commit_message: ${{ github.event.head_commit.message }} ${{steps.tag_version.outputs.tag}}
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -66,8 +67,8 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [build] needs: [build]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: webiste name: webiste
path: website/build path: website/build
@@ -98,33 +99,33 @@ jobs:
docker tag wxmp ${{ secrets.DOCKER_USER }}/wxmp:${{needs.build.outputs.version}} docker tag wxmp ${{ secrets.DOCKER_USER }}/wxmp:${{needs.build.outputs.version}}
docker push ${{ secrets.DOCKER_USER }}/wxmp:${{needs.build.outputs.version}} docker push ${{ secrets.DOCKER_USER }}/wxmp:${{needs.build.outputs.version}}
# Create Docker Image in GitHub # # Create Docker Image in GitHub
- name: Login to GitHub registry # - name: Login to GitHub registry
run: echo ${{ github.token }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin # run: echo ${{ github.token }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build docker image # - name: Build docker image
working-directory: website # working-directory: website
run: docker build -t ghcr.io/jaywcjlove/wxmp:latest . # run: docker build -t ghcr.io/jaywcjlove/wxmp:latest .
- name: Publish to GitHub registry # - name: Publish to GitHub registry
run: docker push ghcr.io/jaywcjlove/wxmp:latest # run: docker push ghcr.io/jaywcjlove/wxmp:latest
- name: Tag docker image (beta) and publish to GitHub registry # - name: Tag docker image (beta) and publish to GitHub registry
if: needs.build.outputs.successful # if: needs.build.outputs.successful
run: | # run: |
echo "version: v${{ needs.build.outputs.version }}" # echo "version: v${{ needs.build.outputs.version }}"
docker tag ghcr.io/jaywcjlove/wxmp:latest ghcr.io/jaywcjlove/wxmp:${{needs.build.outputs.version}} # docker tag ghcr.io/jaywcjlove/wxmp:latest ghcr.io/jaywcjlove/wxmp:${{needs.build.outputs.version}}
docker push ghcr.io/jaywcjlove/wxmp:${{needs.build.outputs.version}} # docker push ghcr.io/jaywcjlove/wxmp:${{needs.build.outputs.version}}
build_windows: build_windows:
needs: [build] needs: [build]
runs-on: windows-latest runs-on: windows-latest
timeout-minutes: 30 timeout-minutes: 30
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: 16 node-version: 20
- name: Install - name: Install
run: npm install --build-from-source run: npm install --build-from-source
@@ -133,7 +134,7 @@ jobs:
- run: npm run build - run: npm run build
# - run: npm run electron # - run: npm run electron
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: webiste name: webiste
path: website/build path: website/build
@@ -143,8 +144,11 @@ jobs:
run: npm run deps run: npm run deps
- run: npm run build:app - run: npm run build:app
- working-directory: electron/app/dist
run: ls -R
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
if: needs.build.outputs.successful == 'true'
with: with:
name: wxmp-windows name: wxmp-windows
path: | path: |
@@ -155,16 +159,16 @@ jobs:
runs-on: macos-latest runs-on: macos-latest
timeout-minutes: 30 timeout-minutes: 30
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: 16 node-version: 20
- run: npm install - run: npm install
- run: npm run hoist - run: npm run hoist
- run: npm run build - run: npm run build
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: webiste name: webiste
path: website/build path: website/build
@@ -174,8 +178,11 @@ jobs:
run: npm run deps run: npm run deps
- run: npm run build:app - run: npm run build:app
- working-directory: electron/app/dist
run: ls -R
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
if: needs.build.outputs.successful == 'true'
with: with:
name: wxmp-macos name: wxmp-macos
path: | path: |
@@ -186,16 +193,16 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 45 timeout-minutes: 45
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: 16 node-version: 20
- run: npm install - run: npm install
- run: npm run hoist - run: npm run hoist
- run: npm run build - run: npm run build
# - run: npm run electron # - run: npm run electron
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: webiste name: webiste
path: website/build path: website/build
@@ -205,8 +212,11 @@ jobs:
run: npm run deps run: npm run deps
- run: npm run build:app - run: npm run build:app
- working-directory: electron/app/dist
run: ls -R
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
if: needs.build.outputs.successful == 'true'
with: with:
name: wxmp-linux name: wxmp-linux
path: | path: |
@@ -216,26 +226,26 @@ jobs:
create_release: create_release:
needs: [build, build_windows, build_macos, build_linux] needs: [build, build_windows, build_macos, build_linux]
if: needs.build.outputs.successful if: needs.build.outputs.successful == 'true'
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 45 timeout-minutes: 45
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: 16 node-version: 20
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: wxmp-linux name: wxmp-linux
path: dist/linux path: dist/linux
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: wxmp-macos name: wxmp-macos
path: dist/macos path: dist/macos
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: wxmp-windows name: wxmp-windows
path: dist/windows path: dist/windows
@@ -246,7 +256,7 @@ jobs:
- name: Generate Changelog - name: Generate Changelog
id: changelog id: changelog
uses: jaywcjlove/changelog-generator@v1.5.7 uses: jaywcjlove/changelog-generator@main
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
filter-author: (jaywcjlove|小弟调调™|dependabot\[bot\]|Renovate Bot) filter-author: (jaywcjlove|小弟调调™|dependabot\[bot\]|Renovate Bot)
@@ -254,34 +264,51 @@ jobs:
- name: Create Release - name: Create Release
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
if: needs.build.outputs.successful if: needs.build.outputs.successful == 'true'
with: with:
allowUpdates: true
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
name: ${{ steps.changelog.outputs.tag }} name: ${{ steps.changelog.outputs.tag }}
tag: ${{ steps.changelog.outputs.tag }} tag: ${{ steps.changelog.outputs.tag }}
artifacts: "dist/linux/*.rpm,dist/linux/*.deb,dist/macos/*.zip,dist/macos/*.dmg,dist/windows/*.exe"
body: | body: |
Documentation ${{ steps.changelog.outputs.tag }}: https://raw.githack.com/jaywcjlove/wxmp/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html Documentation ${{ steps.changelog.outputs.tag }}: https://raw.githack.com/jaywcjlove/wxmp/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html
Comparing Changes: ${{ steps.changelog.outputs.compareurl }} Comparing Changes: ${{ steps.changelog.outputs.compareurl }}
${{ steps.changelog.outputs.changelog }} ${{ steps.changelog.outputs.changelog }}
```bash
docker pull wcjiang/wxmp:${{needs.build.outputs.create_tag_versionNumber}}
```
```bash
docker run --name wxmp --rm -d -p 9666:3000 wcjiang/wxmp:${{ needs.build.outputs.create_tag_versionNumber }}
# Or
docker run --name wxmp -itd -p 9666:3000 wcjiang/wxmp:${{ needs.build.outputs.create_tag_versionNumber }}
```
Visit the following URL in your browser
```bash
http://localhost:9666/
```
roll_back: roll_back:
if: failure() if: failure()
needs: [build, create_release] needs: [build, create_release]
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 4 timeout-minutes: 4
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
with: with:
ref: ${{ github.head_ref }} ref: ${{ github.head_ref }}
- run: echo "outputs.version - ${{ needs.build.outputs.create_tag_version }}" - run: echo "outputs.version - ${{ needs.build.outputs.create_tag_version }}"
- uses: dev-drprasad/delete-tag-and-release@v0.2.0 - uses: dev-drprasad/delete-tag-and-release@v1.1
if: needs.build.outputs.successful if: needs.build.outputs.successful == 'true'
with: with:
delete_release: true delete_release: true
repo: jaywcjlove/wxmp repo: jaywcjlove/wxmp
tag_name: '${{ needs.build.outputs.create_tag_version }}' tag_name: '${{ needs.build.outputs.create_tag_version }}'
env: github_token: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -2,10 +2,15 @@
<h1 align="center">微信公众号 Markdown 编辑器</h1> <h1 align="center">微信公众号 Markdown 编辑器</h1>
</div> </div>
![微信公众号 Markdown 编辑器](https://user-images.githubusercontent.com/1680273/188264183-a6b8cb6a-92e1-4a73-afc5-4f0234b26ed3.png) [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor)
[![CI](https://github.com/jaywcjlove/wxmp/actions/workflows/ci.yml/badge.svg)](https://github.com/jaywcjlove/wxmp/actions/workflows/ci.yml)
[![微信公众号 Markdown 编辑器](https://user-images.githubusercontent.com/1680273/188264183-a6b8cb6a-92e1-4a73-afc5-4f0234b26ed3.png)](https://jaywcjlove.github.io/wxmp)
微信公众号文章 Markdown 在线编辑器,使用 markdown 语法创建一篇简介美观大方的微信公众号图文。由于发版本麻烦,和一些功能无法扩展停滞开发了,未来不再开发 Chrome 的插件(暂存在 chrome 分支),通过 web 版本定制更丰富的功能。 微信公众号文章 Markdown 在线编辑器,使用 markdown 语法创建一篇简介美观大方的微信公众号图文。由于发版本麻烦,和一些功能无法扩展停滞开发了,未来不再开发 Chrome 的插件(暂存在 chrome 分支),通过 web 版本定制更丰富的功能。
[![Markdown 编辑器桌面应用](https://user-images.githubusercontent.com/1680273/188407235-ead43d61-2ef8-416a-926f-396d8b824b33.png)](https://github.com/jaywcjlove/wxmp/releases)
## 功能特性 ## 功能特性
开发计划和一些功能介绍,有需求可以在 issue 中提,使得工具变得更加完善。下面示例用于 web 应用中效果展示。 开发计划和一些功能介绍,有需求可以在 issue 中提,使得工具变得更加完善。下面示例用于 web 应用中效果展示。
@@ -15,11 +20,11 @@
- [x] 支持主题选择 & 编辑预览。 - [x] 支持主题选择 & 编辑预览。
- [x] 支持明暗两种主题预览。 - [x] 支持明暗两种主题预览。
- [ ] 支持代码块主题样式选择。 - [ ] 支持代码块主题样式选择。
- [ ] 支持全局字号大小选择。 - [x] 支持色盘取色,快速替换文章整体色调
- [ ] 支持色盘取色,快速替换文章整体色调
- [x] 支持 URL 参数加载 Markdown 内容。 - [x] 支持 URL 参数加载 Markdown 内容。
- [x] 支持 URL 参数选择预览主题。 - [x] 支持 URL 参数选择预览主题。
- [x] 使用 electron 生成桌面应用。 - [x] CI 自动生成 Electron 桌面应用。
- [ ] ~~支持全局字号大小选择。~~
### 支持代码块样式 ### 支持代码块样式
@@ -126,7 +131,7 @@ Markdown URL 地址: https://raw.githubusercontent.com/jaywcjlove/c-tutorial/mas
## 主题定制 ## 主题定制
在目录 `src/themes` 中存放默认主题,在 `src/store/context.tsx` 中配置主题,主题使用 css 定义样式,不支持复杂的选择器。提供在线主题编辑器,欢迎修改并 PR 进仓库供大家使用。 在目录 `website/src/themes` 中存放默认主题,在 `website/src/store/context.tsx` 中配置主题,主题使用 `css` 定义样式,不支持复杂的选择器。提供在线主题编辑器,欢迎修改并 `PR` 进仓库供大家使用。
```css ```css
/* 1~6 标题样式定义 */ /* 1~6 标题样式定义 */

View File

@@ -2,7 +2,7 @@
"name": "wxmp", "name": "wxmp",
"description": "微信公众号 Markdown 编辑器", "description": "微信公众号 Markdown 编辑器",
"homepage": "https://github.com/jaywcjlove/wxmp.git", "homepage": "https://github.com/jaywcjlove/wxmp.git",
"version": "2.2.0", "version": "2.4.0",
"main": "main.js", "main": "main.js",
"author": "Kenny Wong <398188662@qq.com>", "author": "Kenny Wong <398188662@qq.com>",
"private": true, "private": true,
@@ -18,13 +18,13 @@
"build": "npm run copy && cross-env NODE_ENV=production electron-builder build --publish=never --config config.json" "build": "npm run copy && cross-env NODE_ENV=production electron-builder build --publish=never --config config.json"
}, },
"dependencies": { "dependencies": {
"@wcj/wxmp-main": "2.2.0" "@wcj/wxmp-main": "2.4.0"
}, },
"devDependencies": { "devDependencies": {
"@wcj/wxmp-preload": "2.2.0", "@wcj/wxmp-preload": "2.4.0",
"cpy-cli": "4.2.0", "cpy-cli": "^5.0.0",
"electron": "19.0.5", "electron": "20.1.3",
"electron-builder": "23.1.0", "electron-builder": "23.3.3",
"website": "2.2.0" "website": "2.4.0"
} }
} }

View File

@@ -1,16 +1,16 @@
{ {
"name": "@wcj/wxmp-main", "name": "@wcj/wxmp-main",
"version": "2.2.0", "version": "2.4.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "tsbb build --disable-babel --file-names src/index.ts", "build": "tsbb build",
"watch": "tsbb watch --disable-babel --file-names src/index.ts" "watch": "tsbb watch"
}, },
"files": [ "files": [
"lib" "lib"
], ],
"devDependencies": { "devDependencies": {
"electron": "19.0.5" "electron": "20.1.3"
} }
} }

View File

@@ -14,15 +14,16 @@ export class App {
async createWindow(options: Options = {}, loadURL?: string) { async createWindow(options: Options = {}, loadURL?: string) {
await app.whenReady(); await app.whenReady();
const opts: Options = { const opts: Options = {
titleBarStyle: 'hidden', // 无标题栏 // titleBarStyle: 'hiddenInset', // 无标题栏
frame: false, // 创建无边窗口 // frame: false, // 创建无边窗口
width: 800, width: 850,
height: 600, height: 600,
minWidth: 850, minWidth: 850,
minHeight: 600,
center: true, center: true,
maximizable: true, // maximizable: true,
minimizable: true, // minimizable: true,
resizable: true, // resizable: true,
webPreferences: { webPreferences: {
// 多线程 // 多线程
nodeIntegrationInWorker: true, nodeIntegrationInWorker: true,

View File

@@ -1,16 +1,16 @@
{ {
"name": "@wcj/wxmp-preload", "name": "@wcj/wxmp-preload",
"version": "2.2.0", "version": "2.4.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "tsbb build --disable-babel --file-names src/index.ts", "build": "tsbb build",
"watch": "tsbb watch --disable-babel --file-names src/index.ts" "watch": "tsbb watch"
}, },
"files": [ "files": [
"lib" "lib"
], ],
"devDependencies": { "devDependencies": {
"electron": "19.0.5" "electron": "20.1.3"
} }
} }

View File

@@ -1,18 +1,4 @@
const styleStr = `.siderbar { const styleStr = `.header .logo {}`;
-webkit-app-region: drag;
}
.siderbar header h1 a, github-corners {
display: none;
}
article.content:before {
-webkit-app-region: drag;
position: absolute;
content: ' ';
display: block;
height: 41px;
width: 100%;
z-index: -1;
}`;
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const head = document.querySelector('head'); const head = document.querySelector('head');

View File

@@ -1,4 +1,4 @@
{ {
"version": "2.2.0", "version": "2.4.0",
"packages": ["website", "electron/*"] "packages": ["website", "electron/*"]
} }

View File

@@ -9,18 +9,19 @@
"version": "lerna version --exact --force-publish --no-push --no-git-tag-version", "version": "lerna version --exact --force-publish --no-push --no-git-tag-version",
"prepare": "husky install", "prepare": "husky install",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"pretty-quick": "pretty-quick --staged",
"hoist": "lerna bootstrap --hoist", "hoist": "lerna bootstrap --hoist",
"clean": "lerna clean --yes" "clean": "lerna clean --yes"
}, },
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@lerna/legacy-package-management": "^8.0.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"husky": "^8.0.1", "husky": "^8.0.1",
"lerna": "5.5.0", "lerna": "^8.0.0",
"prettier": "^2.7.1", "prettier": "^3.0.2",
"pretty-quick": "~3.1.3", "react": "~18.2.0",
"tsbb": "^3.7.5" "react-dom": "~18.2.0",
"tsbb": "~4.4.0"
}, },
"workspaces": { "workspaces": {
"packages": [ "packages": [

View File

@@ -20,6 +20,8 @@ export default (conf: Configuration, env: 'development' | 'production', options:
}), }),
); );
/** https://github.com/kktjs/kkt/issues/446 */
conf.ignoreWarnings = [{ module: /node_modules[\\/]parse5[\\/]/ }];
conf.module!.exprContextCritical = false; conf.module!.exprContextCritical = false;
if (env === 'production') { if (env === 'production') {
conf.output = { ...conf.output, publicPath: './' }; conf.output = { ...conf.output, publicPath: './' };

View File

@@ -1,6 +1,6 @@
{ {
"name": "website", "name": "website",
"version": "2.2.0", "version": "2.4.0",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "kkt start", "start": "kkt start",
@@ -25,33 +25,31 @@
"@uiw/codemirror-theme-xcode": "^4.11.6", "@uiw/codemirror-theme-xcode": "^4.11.6",
"@uiw/react-back-to-top": "^1.2.0", "@uiw/react-back-to-top": "^1.2.0",
"@uiw/react-github-corners": "^1.5.15", "@uiw/react-github-corners": "^1.5.15",
"@uiw/react-markdown-editor": "^5.7.0", "@uiw/react-markdown-editor": "^6.0.0",
"@wcj/dark-mode": "^1.0.15", "@wcj/dark-mode": "^1.0.15",
"css-tree": "^2.2.1", "css-tree": "^2.2.1",
"react": "^18.2.0", "react": "~18.2.0",
"react-code-preview-layout": "^2.0.4", "react-dom": "~18.2.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.3.0", "react-hot-toast": "^2.3.0",
"react-router-dom": "^6.3.0", "react-router-dom": "^7.0.0",
"rehype-attr": "^2.0.8", "rehype-attr": "^3.0.0",
"rehype-ignore": "^1.0.1", "rehype-ignore": "^2.0.0",
"rehype-prism-plus": "^1.5.0", "rehype-prism-plus": "^2.0.0",
"rehype-raw": "^6.1.1", "rehype-raw": "^7.0.0",
"rehype-stringify": "^9.0.3", "rehype-stringify": "^10.0.0",
"remark-gfm": "^3.0.1", "remark-gfm": "^4.0.0",
"remark-parse": "^10.0.1", "remark-parse": "^11.0.0",
"remark-rehype": "^10.1.0", "remark-rehype": "^11.0.0",
"styled-components": "^5.3.5", "styled-components": "~6.1.0",
"unified": "^10.1.2" "unified": "^11.0.0"
}, },
"devDependencies": { "devDependencies": {
"@kkt/less-modules": "^7.2.0", "@kkt/less-modules": "^7.2.0",
"@kkt/raw-modules": "^7.2.0", "@kkt/raw-modules": "^7.2.0",
"@kkt/scope-plugin-options": "^7.2.0", "@kkt/scope-plugin-options": "^7.2.0",
"@types/css-tree": "^1.0.7", "@types/css-tree": "^2.3.1",
"@types/react": "^18.0.17", "@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@types/styled-components": "^5.1.25",
"kkt": "^7.2.0", "kkt": "^7.2.0",
"markdown-react-code-preview-loader": "^2.1.2" "markdown-react-code-preview-loader": "^2.1.2"
}, },

View File

@@ -0,0 +1,42 @@
import React, { useContext } from 'react';
import { ICommand } from '@uiw/react-markdown-editor';
import styled from 'styled-components';
import { Context } from '../store/context';
const Input = styled.input`
position: absolute;
opacity: 0;
height: 20px;
width: 20px;
`;
const Button = styled.button``;
const ColorView: React.FC<{}> = (props) => {
const { preColor, setPreColor } = useContext(Context);
const handleChange = (evn: React.ChangeEvent<HTMLInputElement>) => {
setPreColor(evn.target.value);
};
const color = preColor ? preColor : 'currentColor';
return (
<Button type="button">
<svg viewBox="0 0 24 24" fill="none" height="16" width="16">
<path
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
d="M8.203 2.004c1.261 0 2.304 1.103 2.476 2.538l8.483 8.484-7.778 7.778a3 3 0 0 1-4.243 0L2.9 16.562a3 3 0 0 1 0-4.243l2.804-2.805V4.961c0-1.633 1.12-2.957 2.5-2.957Zm.5 2.957v1.553l-1 1V4.961c0-.327.224-.591.5-.591.277 0 .5.264.5.591Zm0 5.914V9.342l-4.39 4.391a1 1 0 0 0 0 1.414l4.243 4.243a1 1 0 0 0 1.414 0l6.364-6.364-5.63-5.63v3.48l-.003.128h-2.01a.698.698 0 0 0 .012-.129Z"
/>
<path d="M16.859 16.875a3 3 0 1 0 4.242 0l-2.121-2.121-2.121 2.12Z" fill={color} />
</svg>
<Input type="color" value={preColor} onChange={handleChange} />
</Button>
);
};
export const colorCommand: ICommand = {
name: 'color',
keyCommand: 'color',
button: () => <ColorView />,
};

View File

@@ -4,30 +4,35 @@ import toast from 'react-hot-toast';
import styled from 'styled-components'; import styled from 'styled-components';
const Button = styled.button` const Button = styled.button`
white-space: nowrap; /* white-space: nowrap;
width: initial !important; width: initial !important;
display: flex; display: flex;
align-items: center; align-items: center; */
padding: 0 0.4rem !important;
`; `;
const CopyView: React.FC<{ command: ICommand; editorProps: IMarkdownEditor & ToolBarProps }> = (props) => { const CopyView: React.FC<{ command: ICommand; editorProps: IMarkdownEditor & ToolBarProps }> = (props) => {
const { editorProps } = props; const { editorProps } = props;
const handleClick = () => { const handleClick = () => {
const dom = editorProps.preview.current; const dom: HTMLDivElement | null = editorProps.preview.current;
dom?.focus(); if (!dom) {
window.getSelection()?.removeAllRanges(); toast.error(<div>dom is null</div>);
let range = document.createRange(); return;
range.setStartBefore(dom?.firstChild!); }
range.setEndAfter(dom?.lastChild!); dom.focus();
window.getSelection()?.addRange(range); const htmlContent = dom.innerHTML;
document.execCommand(`copy`); navigator.clipboard
window.getSelection()?.removeAllRanges(); .writeText(htmlContent)
toast.success(<div></div>); .then(() => {
toast.success(<div></div>);
})
.catch((err) => {
toast.error(<div>{JSON.stringify(err)}</div>);
console.error('Failed to copy: ', err);
});
}; };
return ( return (
<Button type="button" onClick={handleClick}> <Button type="button" onClick={handleClick}>
{props.command.icon} {props.command.icon}
</Button> </Button>
); );
}; };

View File

@@ -4,7 +4,7 @@ import styled from 'styled-components';
const Link = styled(NavLink)` const Link = styled(NavLink)`
font-size: 0.8rem; font-size: 0.8rem;
line-height: 0.8rem; line-height: 0.7rem;
text-decoration: none; text-decoration: none;
padding: 0.18rem 0.3rem; padding: 0.18rem 0.3rem;
&:hover { &:hover {

View File

@@ -12,7 +12,7 @@ const Select = styled.select`
padding: 0 0.2rem 0 0.2rem; padding: 0 0.2rem 0 0.2rem;
margin: 0; margin: 0;
font-family: inherit; font-family: inherit;
font-size: 0.8rem; font-size: 0.7rem;
outline: none; outline: none;
height: 1.15rem; height: 1.15rem;
cursor: inherit; cursor: inherit;
@@ -49,7 +49,6 @@ const ThemePreviewView: React.FC<{}> = () => {
const { setCss, previewTheme, setPreviewTheme } = useContext(Context); const { setCss, previewTheme, setPreviewTheme } = useContext(Context);
const handleChange = (ev: React.ChangeEvent<HTMLSelectElement>) => { const handleChange = (ev: React.ChangeEvent<HTMLSelectElement>) => {
const value = ev.target.value as PreviewThemeValue; const value = ev.target.value as PreviewThemeValue;
console.log('vvvv');
setPreviewTheme(value); setPreviewTheme(value);
setCss(previewThemes[value].value); setCss(previewThemes[value].value);
}; };

View File

@@ -8,14 +8,22 @@ import { ReactComponent as Loading } from '../assets/tail-spin.svg';
import { Context } from '../store/context'; import { Context } from '../store/context';
const Warpper = styled.div``; const Warpper = styled.div``;
const HeaderPlace = styled.div`
position: relative;
height: 2.8rem;
`;
const Header = styled.header` const Header = styled.header`
-webkit-app-region: drag; -webkit-app-region: drag;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
background: var(--color-canvas-default);
border-bottom: 1px solid var(--color-border-muted); border-bottom: 1px solid var(--color-border-muted);
padding: 0.5rem 0.6rem 0.5rem 1rem; padding: 0.5rem 0.6rem 0.5rem 0.8rem;
position: fixed;
width: 100%;
z-index: 9;
`; `;
const Article = styled.article` const Article = styled.article`
@@ -64,14 +72,16 @@ const Section = styled.section`
text-decoration: none; text-decoration: none;
color: var(--color-theme-text); color: var(--color-theme-text);
padding: 0.1rem 0.3rem; padding: 0.1rem 0.3rem;
box-shadow: inset 0 0 0 var(--color-accent-fg);
transition: all 0.3s; transition: all 0.3s;
font-size: 0.9rem; font-size: 0.9rem;
border-radius: 0.2rem;
&.active { &.active {
background-color: var(--color-accent-fg);
box-shadow: inset 0 -0.3rem 0 var(--color-accent-fg); box-shadow: inset 0 -0.3rem 0 var(--color-accent-fg);
color: #fff;
} }
&:hover:not(.active):not(:last-child) { &:hover:not(.active):not(:last-child) {
box-shadow: inset 0 -1.5rem 0 var(--color-accent-fg); background-color: var(--color-accent-fg);
color: #fff; color: #fff;
border-radius: 0.2rem; border-radius: 0.2rem;
} }
@@ -82,25 +92,27 @@ export function Layout() {
const { isLoading } = useContext(Context); const { isLoading } = useContext(Context);
return ( return (
<Warpper className="wmde-markdown-color"> <Warpper className="wmde-markdown-color">
<Header> <HeaderPlace>
<Article> <Header className="header">
<Logo width={28} height={28} /> <Article className="logo">
<Title> <Logo width={28} height={28} />
<Title>
<sup> v{VERSION} </sup>
</Title> <sup> v{VERSION} </sup>
{isLoading && <Loading />} </Title>
</Article> {isLoading && <Loading />}
<Section> </Article>
<NavLink to="/"></NavLink> <Section>
<NavLink to="/editor/theme"></NavLink> <NavLink to="/"></NavLink>
<NavLink to="/doc"></NavLink> <NavLink to="/editor/theme"></NavLink>
<dark-mode permanent dark="Dark" light="Light" /> <NavLink to="/doc"></NavLink>
<a href="https://github.com/jaywcjlove/wxmp" target="__blank"> <dark-mode permanent dark="Dark" light="Light" />
<GithubIcon width={23} height={23} /> <a href="https://github.com/jaywcjlove/wxmp" target="__blank">
</a> <GithubIcon width={23} height={23} />
</Section> </a>
</Header> </Section>
</Header>
</HeaderPlace>
<Outlet /> <Outlet />
</Warpper> </Warpper>
); );

View File

@@ -5,15 +5,16 @@ import { Context } from '../../store/context';
import { markdownToHTML } from '../../utils/markdownToHTML'; import { markdownToHTML } from '../../utils/markdownToHTML';
const Warpper = styled.div` export const Warpper = styled.div`
width: 375px; width: 375px;
padding: 20px; padding: 20px;
box-shadow: 0 0 60px rgb(0 0 0 / 10%); box-shadow: 0 0 60px rgb(0 0 0 / 10%);
min-height: 100%; min-height: 100%;
font-size: 17px;
`; `;
export const Preview = (props: MarkdownPreviewProps) => { export const Preview = (props: MarkdownPreviewProps) => {
const { css } = useContext(Context); const { css, preColor, previewTheme } = useContext(Context);
const html = markdownToHTML(props.source || '', css); const html = markdownToHTML(props.source || '', css, { preColor, previewTheme });
return <Warpper contentEditable spellCheck={false} dangerouslySetInnerHTML={{ __html: html }} />; return <Warpper contentEditable spellCheck={false} dangerouslySetInnerHTML={{ __html: html }} />;
}; };

View File

@@ -1,37 +1,32 @@
import MarkdownEditor, { getCommands } from '@uiw/react-markdown-editor'; import MarkdownEditor, { getCommands } from '@uiw/react-markdown-editor';
import { useContext } from 'react'; import { useContext } from 'react';
// @ts-ignore
import { EditorView } from '@codemirror/view'; import { EditorView } from '@codemirror/view';
import styled from 'styled-components';
import { Preview } from './Preview'; import { Preview } from './Preview';
import { copy } from '../../commands/copy'; import { copy } from '../../commands/copy';
import { colorCommand } from '../../commands/color';
import { theme as themeCommand, previeTheme } from '../../commands/theme'; import { theme as themeCommand, previeTheme } from '../../commands/theme';
import { cssCommand } from '../../commands/css'; import { cssCommand } from '../../commands/css';
import { Context, themes } from '../../store/context'; import { Context, themes } from '../../store/context';
export const Warpper = styled.div`
height: calc(100vh - 2.9rem);
`;
export const HomePage = () => { export const HomePage = () => {
const commands = [...getCommands(), themeCommand]; const commands = [...getCommands(), themeCommand];
const { theme, markdown, isLoading, setMarkdown } = useContext(Context); const { theme, markdown, isLoading, setMarkdown } = useContext(Context);
const themeValue = themes[theme].value; const themeValue = themes[theme].value;
const handleChange = (value: string) => setMarkdown(value); const handleChange = (value: string) => setMarkdown(value);
return ( return (
<Warpper> <MarkdownEditor
<MarkdownEditor value={markdown}
value={markdown} toolbars={commands}
toolbars={commands} theme={themeValue}
theme={themeValue} readOnly={isLoading}
readOnly={isLoading} toolbarsMode={[cssCommand, previeTheme, copy, colorCommand, 'fullscreen', 'preview']}
toolbarsMode={[cssCommand, previeTheme, copy, 'fullscreen', 'preview']} extensions={[EditorView.lineWrapping]}
extensions={[EditorView.lineWrapping]} renderPreview={Preview}
renderPreview={Preview} previewWidth="420px"
previewWidth="420px" onChange={handleChange}
onChange={handleChange} visible={true}
visible={true} height="calc(100vh - 4.6rem)"
height="calc(100vh - 4.70rem)" />
/>
</Warpper>
); );
}; };

View File

@@ -1,19 +1,11 @@
import { MarkdownPreviewProps } from '@uiw/react-markdown-preview';
import styled from 'styled-components';
import { useContext } from 'react'; import { useContext } from 'react';
import { Context } from '../../store/context'; import { Context } from '../../store/context';
import { markdownToHTML } from '../../utils/markdownToHTML'; import { markdownToHTML } from '../../utils/markdownToHTML';
import { Warpper } from '../home/Preview';
const Warpper = styled.div` export const Preview = () => {
width: 375px; const { css, markdown, preColor, previewTheme } = useContext(Context);
padding: 20px; const html = markdownToHTML(markdown, css, { preColor, previewTheme });
box-shadow: 0 0 60px rgb(0 0 0 / 10%);
min-height: 100%;
`;
export const Preview = (props: MarkdownPreviewProps) => {
const { css, markdown } = useContext(Context);
const html = markdownToHTML(markdown, css);
return <Warpper contentEditable spellCheck={false} dangerouslySetInnerHTML={{ __html: html }} />; return <Warpper contentEditable spellCheck={false} dangerouslySetInnerHTML={{ __html: html }} />;
}; };

View File

@@ -8,7 +8,6 @@ import { previousCommand } from '../../commands/css';
import { themeTitle } from '../../commands/title'; import { themeTitle } from '../../commands/title';
import { theme as themeCommand, previeTheme } from '../../commands/theme'; import { theme as themeCommand, previeTheme } from '../../commands/theme';
import { Context, themes } from '../../store/context'; import { Context, themes } from '../../store/context';
import { Warpper } from '../home';
export const EditorPage = () => { export const EditorPage = () => {
const commands = [themeTitle, themeCommand, previousCommand]; const commands = [themeTitle, themeCommand, previousCommand];
@@ -17,20 +16,18 @@ export const EditorPage = () => {
const value = themes[theme].value; const value = themes[theme].value;
const handleChange = (value: string) => setCss(value); const handleChange = (value: string) => setCss(value);
return ( return (
<Warpper> <MarkdownEditor
<MarkdownEditor value={css}
value={css} theme={value}
theme={value} readOnly={isLoading}
readOnly={isLoading} toolbars={commands}
toolbars={commands} toolbarsMode={toolbarsMode}
toolbarsMode={toolbarsMode} reExtensions={[EditorView.lineWrapping, cssLang()]}
reExtensions={[EditorView.lineWrapping, cssLang()]} renderPreview={Preview}
renderPreview={Preview} previewWidth="420px"
previewWidth="420px" onChange={handleChange}
onChange={handleChange} visible={true}
visible={true} height="calc(100vh - 4.6rem)"
height="calc(100vh - 4.92rem)" />
/>
</Warpper>
); );
}; };

View File

@@ -12,6 +12,9 @@ export const Provider: React.FC<React.PropsWithChildren> = ({ children }) => {
const [css, setCss] = React.useState<string>(previewThemes[initPreviewTheme].value); const [css, setCss] = React.useState<string>(previewThemes[initPreviewTheme].value);
const [previewTheme, setPreviewTheme] = React.useState<PreviewThemeValue>(initPreviewTheme); const [previewTheme, setPreviewTheme] = React.useState<PreviewThemeValue>(initPreviewTheme);
const [theme, setTheme] = React.useState<ThemeValue>('default'); const [theme, setTheme] = React.useState<ThemeValue>('default');
const [preColor, setPreColor] = React.useState<string>(
previewThemes[initPreviewTheme] ? previewThemes[initPreviewTheme].color : '',
);
const [isLoading, setIsLoading] = React.useState<boolean>(true); const [isLoading, setIsLoading] = React.useState<boolean>(true);
const { data: mddata, isLoading: loading } = useMdSource(mdurl); const { data: mddata, isLoading: loading } = useMdSource(mdurl);
useEffect(() => { useEffect(() => {
@@ -26,9 +29,12 @@ export const Provider: React.FC<React.PropsWithChildren> = ({ children }) => {
} }
}, [mddata, mdurl]); }, [mddata, mdurl]);
useEffect(() => setIsLoading(loading), [loading]); useEffect(() => setIsLoading(loading), [loading]);
useEffect(() => setPreColor(previewThemes[initPreviewTheme].color), [initPreviewTheme]);
return ( return (
<Context.Provider <Context.Provider
value={{ value={{
preColor,
setPreColor,
isLoading, isLoading,
setIsLoading, setIsLoading,
markdown, markdown,

View File

@@ -97,25 +97,64 @@ export const previewThemes = {
default: { default: {
label: '翡翠绿', label: '翡翠绿',
value: defStyle, value: defStyle,
color: '#009874',
}, },
simple: { simple: {
label: '简洁蓝', label: '简洁蓝',
value: simpleStyle, value: simpleStyle,
color: '#0f4c81',
}, },
underscore: { underscore: {
label: '下划线黄', label: '下划线黄',
value: underscoreStyle, value: underscoreStyle,
color: '#ffb11b',
}, },
base: { base: {
label: '简洁', label: '简洁',
value: baseStyle, value: baseStyle,
color: '',
}, },
}; };
/** 用于全局主题替换样式 */
export const replaceData: Record<PreviewThemeValue, ReplaceData[]> = {
underscore: [
{ select: 'a', name: 'color', value: '{{color}}' },
{ select: 'h1', name: 'box-shadow', value: 'inset 0 -0.9rem 0 0 {{color}}' },
{ select: 'h2', name: 'box-shadow', value: 'inset 0 -0.7rem 0 0 {{color}}' },
{ select: 'h3', name: 'border-left', value: '5px solid {{color}}' },
],
default: [
{ select: 'a', name: 'color', value: '{{color}}' },
{ select: 'h1', name: 'border-bottom', value: '3px solid {{color}}' },
{ select: 'h2', name: 'background', value: '{{color}}' },
{ select: 'h3', name: 'border-left', value: '5px solid {{color}}' },
],
simple: [
{ select: 'a', name: 'color', value: '{{color}}' },
{ select: 'h1', name: 'border-bottom', value: '3px solid {{color}}' },
{ select: 'h2', name: 'background', value: '{{color}}' },
{ select: 'h3', name: 'border-left', value: '5px solid {{color}}' },
{ select: '.code-spans', name: 'color', value: '{{color}}' },
],
base: [],
};
export type ReplaceData = {
select: string;
name: string;
value: string;
};
export const colors = (Object.keys(previewThemes) as Array<keyof typeof previewThemes>).map(
(key) => previewThemes[key].color,
);
export type ThemeValue = keyof typeof themes; export type ThemeValue = keyof typeof themes;
export type PreviewThemeValue = keyof typeof previewThemes; export type PreviewThemeValue = keyof typeof previewThemes;
export interface CreateContext { export interface CreateContext {
preColor: string;
setPreColor: React.Dispatch<React.SetStateAction<string>>;
isLoading: boolean; isLoading: boolean;
setIsLoading: React.Dispatch<React.SetStateAction<boolean>>; setIsLoading: React.Dispatch<React.SetStateAction<boolean>>;
markdown: string; markdown: string;
@@ -129,6 +168,8 @@ export interface CreateContext {
} }
export const Context = React.createContext<CreateContext>({ export const Context = React.createContext<CreateContext>({
preColor: '',
setPreColor: () => {},
isLoading: true, isLoading: true,
setIsLoading: () => {}, setIsLoading: () => {},
markdown: data.source, markdown: data.source,

View File

@@ -5,14 +5,14 @@ a {
h1 { h1 {
color: inherit; color: inherit;
font-size: 1.5rem; font-size: 18px;
font-weight: bold; font-weight: bold;
} }
h2 { h2 {
color: inherit; color: inherit;
margin: 2.5rem 0 1rem 0; margin: 2.5rem 0 1rem 0;
font-size: 1.3em; font-size: 16px;
font-weight: bold; font-weight: bold;
} }
@@ -20,19 +20,20 @@ h3 {
color: inherit; color: inherit;
margin: 1em 0 1em 0; margin: 1em 0 1em 0;
font-weight: bold; font-weight: bold;
font-size: 1em; font-size: 14px;
} }
h4 { h4 {
color: inherit; color: inherit;
margin: 0.6em 0 0.6em 0; margin: 0.6em 0 0.6em 0;
font-weight: bold; font-weight: bold;
font-size: 0.9em; font-size: 12px;
} }
p { p {
color: initial; color: initial;
font-size: 0.85em; font-size: 16px;
line-height: 1.5em;
} }
ul { ul {
@@ -45,13 +46,15 @@ ol {
li { li {
margin: 0; margin: 0;
font-size: 0.85em; font-size: 14px;
line-height: 1.5em;
} }
blockquote { blockquote {
font-style: normal; font-style: normal;
border-left: none; border-left: none;
margin: 1em 0; margin: 1em 0;
line-height: 1.5em;
} }
pre { pre {
@@ -60,7 +63,7 @@ pre {
padding: 1em; padding: 1em;
color: rgb(51, 51, 51); color: rgb(51, 51, 51);
background: rgb(248, 248, 248); background: rgb(248, 248, 248);
font-size: 0.85em; font-size: 14px;
font-weight: 400; font-weight: 400;
letter-spacing: normal; letter-spacing: normal;
word-spacing: 0px; word-spacing: 0px;
@@ -73,7 +76,7 @@ table {
width: 100% !important; width: 100% !important;
border-collapse: collapse; border-collapse: collapse;
line-height: 1.35; line-height: 1.35;
font-size: 0.85em; font-size: 14px;
} }
td { td {
@@ -90,7 +93,7 @@ th {
.code-highlight { .code-highlight {
text-align: left; text-align: left;
font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace; font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace;
font-size: 0.85em; font-size: 14px;
margin: 0px; margin: 0px;
white-space: nowrap; white-space: nowrap;
} }
@@ -117,14 +120,14 @@ th {
display: table; display: table;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1em; font-size: 14px;
font-weight: bold; font-weight: bold;
margin: 3rem 0 0.6rem 0; margin: 3rem 0 0.6rem 0;
padding-left: 0.2rem; padding-left: 0.2rem;
} }
.footnotes-list { .footnotes-list {
font-size: 0.75em; font-size: 10px;
font-style: italic; font-style: italic;
line-height: 1.2; line-height: 1.2;
margin: 0.4rem 0; margin: 0.4rem 0;

View File

@@ -1,7 +1,7 @@
a { a {
color: #576b95; color: #009874;
text-decoration: none; text-decoration: none;
font-size: 0.85em; font-size: 14px;
} }
h1 { h1 {
@@ -11,11 +11,11 @@ h1 {
line-height: 1.75; line-height: 1.75;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1em; font-size: 18px;
font-weight: bold; font-weight: bold;
margin: 2em auto 1em; margin: 2em auto 1em;
padding: 0 1em; padding: 0 1em;
border-bottom: 2px solid #009874; border-bottom: 3px solid #009874;
margin-top: 0; margin-top: 0;
} }
@@ -26,7 +26,7 @@ h2 {
line-height: 1.75; line-height: 1.75;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1.3em; font-size: 16px;
font-weight: bold; font-weight: bold;
margin: 4em auto 2em; margin: 4em auto 2em;
padding: 0 0.3em; padding: 0 0.3em;
@@ -34,21 +34,17 @@ h2 {
background: #009874; background: #009874;
} }
p {
font-size: 0.85em;
}
h3 { h3 {
text-align: left; text-align: left;
color: #3f3f3f; color: #3f3f3f;
line-height: 1.2; line-height: 1.2;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1.1em; font-size: 14px;
font-weight: bold; font-weight: bold;
margin: 2em 8px 0.75em 0; margin: 2em 8px 0.75em 0;
padding-left: 8px; padding-left: 8px;
border-left: 3px solid #009874; border-left: 5px solid #009874;
} }
ul { ul {
@@ -62,22 +58,29 @@ ol {
li { li {
margin: 0; margin: 0;
line-height: 1.5em; line-height: 1.5em;
color: rgb(30 41 59); font-size: 14px;
font-size: 0.85em; line-height: 1.5em;
}
p {
font-size: 16px;
line-height: 1.5em;
padding: 0.5em 0 !important;
margin-bottom: 0 !important;
margin-top: 0 !important;
} }
blockquote { blockquote {
text-align: left; text-align: left;
line-height: 1.75;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 0.85em; font-size: 14px;
font-style: normal; font-style: normal;
border-left: none; border-left: none;
padding: 0.1rem 1rem; padding: 0.5em 1em;
border-radius: 4px; border-radius: 4px;
background: rgba(27, 31, 35, 0.05); background: rgba(27, 31, 35, 0.05);
margin: 1rem 0; margin: 1em 0;
} }
pre { pre {
@@ -111,7 +114,7 @@ table {
width: 100% !important; width: 100% !important;
border-collapse: collapse; border-collapse: collapse;
line-height: 1.35; line-height: 1.35;
font-size: 0.85em; font-size: 14px;
} }
td { td {
@@ -129,7 +132,7 @@ th {
text-align: left; text-align: left;
line-height: 1.75; line-height: 1.75;
font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace; font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace;
font-size: 0.85em; font-size: 14px;
margin: 0px; margin: 0px;
white-space: nowrap; white-space: nowrap;
} }
@@ -143,7 +146,7 @@ th {
text-align: left; text-align: left;
line-height: 1; line-height: 1;
white-space: initial; white-space: initial;
color: #009874; color: #333;
background: rgba(27, 31, 35, 0.05); background: rgba(27, 31, 35, 0.05);
padding: 0.1em 0.3em; padding: 0.1em 0.3em;
border-radius: 0.3em; border-radius: 0.3em;
@@ -157,14 +160,14 @@ th {
display: table; display: table;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1em; font-size: 14px;
font-weight: bold; font-weight: bold;
margin: 3em 0 0.6em 0; margin: 3em 0 0.6em 0;
padding-left: 0.2em; padding-left: 0.2em;
} }
.footnotes-list { .footnotes-list {
font-size: 0.75em; font-size: 10px;
font-style: italic; font-style: italic;
line-height: 1.2; line-height: 1.2;
margin: 0.4rem 0; margin: 0.4rem 0;

View File

@@ -1,7 +1,7 @@
a { a {
color: #576b95; color: #0f4c81;
text-decoration: none; text-decoration: none;
font-size: 0.85em; font-size: 14px;
} }
h1 { h1 {
@@ -11,11 +11,11 @@ h1 {
line-height: 1.75; line-height: 1.75;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1.2em; font-size: 18px;
font-weight: bold; font-weight: bold;
margin: 2em auto 1em; margin: 2em auto 1em;
padding: 0 1em; padding: 0 1em;
border-bottom: 2px solid #0f4c81; border-bottom: 3px solid #0f4c81;
margin-top: 0; margin-top: 0;
} }
@@ -26,7 +26,7 @@ h2 {
line-height: 1.75; line-height: 1.75;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1.2em; font-size: 16px;
font-weight: bold; font-weight: bold;
margin: 4em auto 2em; margin: 4em auto 2em;
padding: 0 0.3em; padding: 0 0.3em;
@@ -34,21 +34,17 @@ h2 {
background: #0f4c81; background: #0f4c81;
} }
p {
font-size: 0.85em;
}
h3 { h3 {
text-align: left; text-align: left;
color: #3f3f3f; color: #3f3f3f;
line-height: 1.2; line-height: 1.2;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1.1em; font-size: 14px;
font-weight: bold; font-weight: bold;
margin: 2em 8px 0.75em 0; margin: 2em 8px 0.75em 0;
padding-left: 8px; padding-left: 8px;
border-left: 3px solid #0f4c81; border-left: 5px solid #0f4c81;
} }
ul { ul {
@@ -62,22 +58,29 @@ ol {
li { li {
margin: 0; margin: 0;
line-height: 1.5em; line-height: 1.5em;
color: rgb(30 41 59); font-size: 14px;
font-size: 0.85em; line-height: 1.5em;
}
p {
font-size: 16px;
line-height: 1.5em;
padding: 0.5em 0 !important;
margin-bottom: 0 !important;
margin-top: 0 !important;
} }
blockquote { blockquote {
text-align: left; text-align: left;
line-height: 1.75;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 0.85em; font-size: 14px;
font-style: normal; font-style: normal;
border-left: none; border-left: none;
padding: 0.1rem 1rem; padding: 0.5em 1em;
border-radius: 4px; border-radius: 4px;
background: rgba(27, 31, 35, 0.05); background: rgba(27, 31, 35, 0.05);
margin: 1rem 0; margin: 1em 0;
} }
pre { pre {
@@ -111,7 +114,7 @@ table {
width: 100% !important; width: 100% !important;
border-collapse: collapse; border-collapse: collapse;
line-height: 1.35; line-height: 1.35;
font-size: 0.85em; font-size: 14px;
} }
td { td {
@@ -129,7 +132,7 @@ th {
text-align: left; text-align: left;
line-height: 1.75; line-height: 1.75;
font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace; font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace;
font-size: 0.85em; font-size: 14px;
margin: 0px; margin: 0px;
white-space: nowrap; white-space: nowrap;
} }
@@ -148,7 +151,7 @@ th {
padding: 0.1em 0.3em; padding: 0.1em 0.3em;
border-radius: 0.3em; border-radius: 0.3em;
font-weight: bold; font-weight: bold;
font-size: 1em; font-size: 14px;
top: -0.1em; top: -0.1em;
position: relative; position: relative;
} }
@@ -157,14 +160,14 @@ th {
display: table; display: table;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1em; font-size: 14px;
font-weight: bold; font-weight: bold;
margin: 3em 0 0.6em 0; margin: 3em 0 0.6em 0;
padding-left: 0.2em; padding-left: 0.2em;
} }
.footnotes-list { .footnotes-list {
font-size: 0.75em; font-size: 10px;
font-style: italic; font-style: italic;
line-height: 1.2; line-height: 1.2;
margin: 0.4rem 0; margin: 0.4rem 0;

View File

@@ -1,7 +1,7 @@
a { a {
color: #576b95; color: #ffb11b;
text-decoration: none; text-decoration: none;
font-size: 0.85em; font-size: 14px;
} }
h1 { h1 {
@@ -11,7 +11,7 @@ h1 {
line-height: 1.15; line-height: 1.15;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1.3em; font-size: 18px;
font-weight: bold; font-weight: bold;
margin: 2em auto 1em; margin: 2em auto 1em;
padding: 0 1em 0.3em 1em; padding: 0 1em 0.3em 1em;
@@ -24,24 +24,20 @@ h2 {
line-height: 1.35; line-height: 1.35;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1.2em; font-size: 16px;
font-weight: bold; font-weight: bold;
padding: 0 0.3em; padding: 0 0.3em;
margin: 2em 0 1em 0; margin: 2em 0 1em 0;
box-shadow: inset 0 -0.7rem 0 0 #ffb11b; box-shadow: inset 0 -0.7rem 0 0 #ffb11b;
} }
p {
font-size: 0.85em;
}
h3 { h3 {
text-align: left; text-align: left;
color: #3f3f3f; color: #3f3f3f;
line-height: 1.2; line-height: 1.2;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1.1em; font-size: 14px;
font-weight: bold; font-weight: bold;
margin: 2em 8px 0.75em 0; margin: 2em 8px 0.75em 0;
padding-left: 8px; padding-left: 8px;
@@ -59,22 +55,29 @@ ol {
li { li {
margin: 0; margin: 0;
line-height: 1.5em; line-height: 1.5em;
color: rgb(30 41 59); font-size: 14px;
font-size: 0.85em; }
p {
font-size: 16px;
line-height: 1.5em;
padding: 0.5em 0 !important;
margin-bottom: 0 !important;
margin-top: 0 !important;
} }
blockquote { blockquote {
text-align: left; text-align: left;
line-height: 1.75; line-height: 1.5em;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 0.85em; font-size: 14px;
font-style: normal; font-style: normal;
border-left: none; border-left: none;
padding: 0.1rem 1rem; padding: 0.5em 1em;
border-radius: 4px; border-radius: 4px;
background: rgba(27, 31, 35, 0.05); background: rgba(27, 31, 35, 0.05);
margin: 1rem 0; margin: 1em 0;
} }
pre { pre {
@@ -108,7 +111,7 @@ table {
width: 100% !important; width: 100% !important;
border-collapse: collapse; border-collapse: collapse;
line-height: 1.35; line-height: 1.35;
font-size: 0.85em; font-size: 14px;
} }
td { td {
@@ -126,7 +129,7 @@ th {
text-align: left; text-align: left;
line-height: 1.75; line-height: 1.75;
font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace; font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace;
font-size: 0.85em; font-size: 14px;
margin: 0px; margin: 0px;
white-space: nowrap; white-space: nowrap;
} }
@@ -140,12 +143,12 @@ th {
text-align: left; text-align: left;
line-height: 1; line-height: 1;
white-space: initial; white-space: initial;
color: #ffb11b; color: #333;
background: rgba(27, 31, 35, 0.05); background: rgba(27, 31, 35, 0.05);
padding: 0.1em 0.3em; padding: 0.1em 0.3em;
border-radius: 0.3em; border-radius: 0.3em;
font-weight: bold; font-weight: bold;
font-size: 1em; font-size: 14px;
top: -0.1em; top: -0.1em;
position: relative; position: relative;
} }
@@ -154,14 +157,14 @@ th {
display: table; display: table;
font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;
font-size: 1em; font-size: 14px;
font-weight: bold; font-weight: bold;
margin: 3em 0 0.6em 0; margin: 3em 0 0.6em 0;
padding-left: 0.2em; padding-left: 0.2em;
} }
.footnotes-list { .footnotes-list {
font-size: 0.75em; font-size: 10px;
font-style: italic; font-style: italic;
line-height: 1.2; line-height: 1.2;
margin: 0.4rem 0; margin: 0.4rem 0;

View File

@@ -1,20 +1,55 @@
import { RootContent, Element, Text, Root } from 'hast'; import { RootContent, Element, Text, Root } from 'hast';
import { PreviewThemeValue, replaceData, ReplaceData } from '../store/context';
export const getBlock = (data: any, str: string = '') => { /**
* {
* "replace": [
* { select: 'a', name: 'color', value: 'red' },
* { select: 'h1', name: 'box-shadow', value: 'red' },
* { select: 'h2', name: 'box-shadow', value: 'red' },
* { select: 'h3', name: 'border-left', value: 'red' },
* { select: 'h3', name: 'color', value: 'red' },
* ]
* }
*/
type BlockOption = {
replace?: Array<ReplaceData>;
};
export const getBlock = (data: any, str: string = '', opts: BlockOption = {}) => {
const { replace } = opts;
if (data && data.data && data.data.type === 'Declaration') { if (data && data.data && data.data.type === 'Declaration') {
str = `${data.data.property}: ${data.data.value.value}${data.data.important ? ' !important' : ''};`; const value = replace?.find((m) => m.name === data.data.property)?.value || data.data.value.value;
// console.log(value)
str = `${data.data.property}: ${value}${data.data.important ? ' !important' : ''};`;
if (data.next) { if (data.next) {
str += getBlock(data.next); str += getBlock(data.next, '', opts);
} }
} }
return str; return str;
}; };
export const cssdata = (list: any, result: Record<string, string> = {}) => { type Cssdata = {
theme?: PreviewThemeValue;
color?: string;
};
export const cssdata = (list: any, result: Record<string, string> = {}, opts: Cssdata = {}) => {
if (list.data && list.data.type === 'Rule') { if (list.data && list.data.type === 'Rule') {
result[list.data.prelude.value] = getBlock(list.data.block.children.head); const selector = list.data.prelude.value;
const options: BlockOption = {};
// console.log('opts:', opts)
if (opts.color && opts.theme && replaceData[opts.theme]) {
options.replace = replaceData[opts.theme]
.filter((m) => m.select === selector)
.map((m) => ({
...m,
value: m.value.replace('{{color}}', opts.color!),
}));
}
result[selector] = getBlock(list.data.block.children.head, '', options);
if (list.next) { if (list.next) {
result = cssdata(list.next, { ...result }); result = cssdata(list.next, { ...result }, opts);
} }
} }
return result; return result;
@@ -29,7 +64,6 @@ export const spaceEscape = (node: RootContent) => {
} }
node.properties.className = className.filter((str: string) => !/(token|control-flow)/.test(str)); node.properties.className = className.filter((str: string) => !/(token|control-flow)/.test(str));
} }
node.children.map((elm) => { node.children.map((elm) => {
if (elm.type === 'element' && elm.children) { if (elm.type === 'element' && elm.children) {
spaceEscape(elm); spaceEscape(elm);
@@ -95,7 +129,7 @@ export const footnotesLabel = (node: Element) => {
]; ];
}; };
export const imagesStyle = (node: Element, parent: Root | Element | null) => { export const imagesStyle = (node: Element, parent: Root | Element | undefined) => {
if ( if (
parent?.type === 'element' && parent?.type === 'element' &&
/(p|a)/.test(parent.tagName) && /(p|a)/.test(parent.tagName) &&

View File

@@ -13,9 +13,12 @@ import rehypeRewrite from 'rehype-rewrite';
import stringify from 'rehype-stringify'; import stringify from 'rehype-stringify';
import { cssdata, spaceEscape, footnotes, footnotesLabel, imagesStyle } from './css'; import { cssdata, spaceEscape, footnotes, footnotesLabel, imagesStyle } from './css';
export type MarkdownToHTMLOptions = {}; export type MarkdownToHTMLOptions = {
preColor?: string;
previewTheme?: string;
};
export function markdownToHTML(md: string, css: string, options: MarkdownToHTMLOptions = {}) { export function markdownToHTML(md: string, css: string, opts: MarkdownToHTMLOptions = {}) {
const ast = csstree.parse(css, { const ast = csstree.parse(css, {
parseAtrulePrelude: false, parseAtrulePrelude: false,
parseRulePrelude: false, parseRulePrelude: false,
@@ -23,19 +26,21 @@ export function markdownToHTML(md: string, css: string, options: MarkdownToHTMLO
parseCustomProperty: false, parseCustomProperty: false,
positions: false, positions: false,
}); });
// @ts-ignore // @ts-ignore
const data = cssdata(ast.children.head); const data = cssdata(ast.children.head, {}, { color: opts.preColor, theme: opts.previewTheme });
const processor = unified() const processor = unified()
.use(remarkParse) .use(remarkParse)
.use(remarkGfm) .use(remarkGfm)
.use(remarkRehype, { allowDangerousHtml: true }) .use(remarkRehype, { allowDangerousHtml: true })
.use(rehypePrism)
.use(rehypeRaw) .use(rehypeRaw)
.use(rehypePrism, {
ignoreMissing: true,
})
.use(rehypeIgnore, {}) .use(rehypeIgnore, {})
.use(rehypeAttrs, { properties: 'attr' }) .use(rehypeAttrs, { properties: 'attr' })
.use(rehypeRewrite, { .use(rehypeRewrite, {
rewrite: (node, index, parent) => { rewrite: (node, _index, parent) => {
// @ts-ignore
if ( if (
node?.type === 'element' && node?.type === 'element' &&
node?.tagName === 'code' && node?.tagName === 'code' &&