Initial public release of MDEditor

This commit is contained in:
sinmb79
2026-03-30 11:45:27 +09:00
commit 7a27714040
43 changed files with 13498 additions and 0 deletions

5165
src-tauri/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

21
src-tauri/Cargo.toml Normal file
View File

@@ -0,0 +1,21 @@
[package]
name = "mdeditor"
version = "0.1.0"
description = "Windows-first offline WYSIWYG Markdown editor"
authors = ["22B Labs"]
edition = "2021"
[lib]
name = "mdeditor_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2", features = [] }
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri = { version = "2", features = [] }
tauri-plugin-dialog = "2"
tauri-plugin-fs = "2"
tauri-plugin-shell = "2"

View File

@@ -0,0 +1,5 @@
Place the Pandoc sidecar binary here before packaging.
- Expected base name: `pandoc`
- Tauri will append the platform-specific suffix during bundling.
- Example Windows file: `pandoc-x86_64-pc-windows-msvc.exe`

3
src-tauri/build.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main MDEditor window",
"windows": ["main"],
"permissions": [
"core:default",
"dialog:default",
"fs:default",
{
"identifier": "shell:allow-execute",
"allow": [
{
"name": "pandoc",
"sidecar": true
}
]
}
]
}

View File

@@ -0,0 +1,33 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bg" x1="72" y1="56" x2="432" y2="456" gradientUnits="userSpaceOnUse">
<stop stop-color="#0F766E" />
<stop offset="1" stop-color="#1D4ED8" />
</linearGradient>
<linearGradient id="paper" x1="150" y1="118" x2="360" y2="390" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFFFFF" />
<stop offset="1" stop-color="#DCEAFE" />
</linearGradient>
</defs>
<rect x="32" y="32" width="448" height="448" rx="96" fill="url(#bg)" />
<path
d="M158 110C158 98.9543 166.954 90 178 90H290.686C295.991 90 301.079 92.1071 304.828 95.8579L353.142 144.172C356.893 147.921 359 153.009 359 158.314V334C359 345.046 350.046 354 339 354H178C166.954 354 158 345.046 158 334V110Z"
fill="url(#paper)"
/>
<path
d="M291 90V141C291 152.046 299.954 161 311 161H359"
stroke="#BFDBFE"
stroke-width="22"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M172 386C172 374.954 180.954 366 192 366H337C348.046 366 357 374.954 357 386C357 397.046 348.046 406 337 406H192C180.954 406 172 397.046 172 386Z"
fill="#0B1220"
fill-opacity="0.22"
/>
<path
d="M194 338V179H228L258 242L288 179H322V338H289V238L266 287H250L227 238V338H194Z"
fill="#0F172A"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src-tauri/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
src-tauri/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

50
src-tauri/src/lib.rs Normal file
View File

@@ -0,0 +1,50 @@
use serde::Serialize;
use tauri::Manager;
use tauri_plugin_shell::ShellExt;
#[derive(Debug, Serialize)]
struct ExportResponse {
output_path: String,
}
#[tauri::command]
async fn export_pdf(app: tauri::AppHandle, input_path: String, output_path: String) -> Result<ExportResponse, String> {
let sidecar_command = app
.shell()
.sidecar("pandoc")
.map_err(|error| format!("failed to prepare pandoc sidecar: {error}"))?;
let output = sidecar_command
.args([input_path.as_str(), "-o", output_path.as_str()])
.output()
.await
.map_err(|error| format!("failed to execute pandoc: {error}"))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
return Err(if stderr.is_empty() {
"pandoc export failed".to_string()
} else {
stderr
});
}
Ok(ExportResponse { output_path })
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![export_pdf])
.setup(|app| {
if let Some(window) = app.get_webview_window("main") {
let _ = window.set_title("MDEditor");
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

5
src-tauri/src/main.rs Normal file
View File

@@ -0,0 +1,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
mdeditor_lib::run();
}

34
src-tauri/tauri.conf.json Normal file
View File

@@ -0,0 +1,34 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "MDEditor",
"version": "0.1.0",
"identifier": "com.22blabs.mdeditor",
"build": {
"beforeBuildCommand": "npm run build",
"beforeDevCommand": "npm run dev -- --host 0.0.0.0 --port 1420",
"devUrl": "http://localhost:1420",
"frontendDist": "../dist"
},
"app": {
"windows": [
{
"label": "main",
"title": "MDEditor",
"width": 1440,
"height": 960,
"resizable": true
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": ["nsis"],
"copyright": "22B Labs",
"category": "Productivity",
"externalBin": ["binaries/pandoc"],
"shortDescription": "Offline WYSIWYG Markdown editor for Korean document workflows"
}
}