Configure Renovate #1
6 changed files with 515 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
target
|
282
Cargo.lock
generated
Normal file
282
Cargo.lock
generated
Normal file
|
@ -0,0 +1,282 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "logseq-export"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
edition = "2021"
|
||||
name = "logseq-export"
|
||||
version = "0.1.0"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
clap = {version = "4.5.23", features = ["derive"]}
|
||||
regex = "1.11.1"
|
9
LICENSE
Normal file
9
LICENSE
Normal file
|
@ -0,0 +1,9 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Kohei Watanabe
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
37
README.md
Normal file
37
README.md
Normal file
|
@ -0,0 +1,37 @@
|
|||
# logseq-export
|
||||
|
||||
このツールは Logseq のデータを Obsidian Vault として変換して出力するためのものです。
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 引数
|
||||
|
||||
- `-i, --input`: 入力ディレクトリ
|
||||
- `-o, --output`: 出力ディレクトリ
|
||||
|
||||
### 実行例
|
||||
|
||||
```
|
||||
$ cargo install --git https://git.fogtype.com/nebel/logseq-export.git
|
||||
$ logseq-export --input path/to/logseq --output path/to/obsidian
|
||||
```
|
||||
|
||||
## 調整事項
|
||||
|
||||
- インデントの調整
|
||||
- トップレベルの箇条書き記号の削除
|
||||
- `{{video URL}}` の変換
|
||||
- 画像サイズ指定の削除(例: `![alt](url){:height 100, :width 200}` -> `![alt](url)`)
|
||||
- 特定の行(`collapsed::`, `id::`, `title::`)の無視
|
||||
|
||||
## 開発方法
|
||||
|
||||
```
|
||||
$ git clone https://git.fogtype.com/nebel/logseq-export.git
|
||||
$ cd logseq-export
|
||||
$ cargo build
|
||||
```
|
||||
|
||||
## ライセンス
|
||||
|
||||
MIT
|
177
src/main.rs
Normal file
177
src/main.rs
Normal file
|
@ -0,0 +1,177 @@
|
|||
use clap::Parser;
|
||||
use regex::Regex;
|
||||
use std::io::Write;
|
||||
use std::{fs::File, path::Path};
|
||||
|
||||
const LIST_LINE_PATTERN: &str = r"^\s*-(?: |$)";
|
||||
const IGNORE_LINE_PATTERN: &str = r"^\s*(?:collapsed|id|title)::";
|
||||
|
||||
fn replace_video(line: &str) -> String {
|
||||
let re = Regex::new(r"\{\{video (.+?)\}\}").unwrap();
|
||||
|
||||
re.replace_all(line, "![]($1)").to_string()
|
||||
}
|
||||
|
||||
fn remove_image_size(line: &str) -> String {
|
||||
let re = Regex::new(r"!\[(.*?)\][(](.+?)[)]\{:height\s*\d+,\s*:width\s*\d+\}").unwrap();
|
||||
|
||||
re.replace_all(line, "![$1]($2)").to_string()
|
||||
}
|
||||
|
||||
fn remove_bullets(line: &str) -> String {
|
||||
let re = Regex::new(LIST_LINE_PATTERN).unwrap();
|
||||
|
||||
re.replace(line, "").to_string()
|
||||
}
|
||||
|
||||
fn dedent(line: &str, indent: usize) -> String {
|
||||
let re = Regex::new(&format!(r"^\s{{0,{}}}", indent * 2)).unwrap();
|
||||
|
||||
re.replace(line, "").to_string()
|
||||
}
|
||||
|
||||
fn process_line(
|
||||
line: &str,
|
||||
is_list: bool,
|
||||
indent: usize,
|
||||
prev_indent: usize,
|
||||
is_code_block: &mut bool,
|
||||
) -> String {
|
||||
let mut line = replace_video(line);
|
||||
line = remove_image_size(&line);
|
||||
line = remove_bullets(&line);
|
||||
|
||||
if line.starts_with("```") {
|
||||
*is_code_block = !*is_code_block;
|
||||
}
|
||||
|
||||
if *is_code_block {
|
||||
return dedent(&line, indent);
|
||||
}
|
||||
|
||||
line = dedent(&line, 1);
|
||||
|
||||
let is_quoted = line.starts_with(">");
|
||||
|
||||
if indent == 0 {
|
||||
if prev_indent == 0 && is_quoted {
|
||||
line = format!("{}{}", " ".repeat(indent), line);
|
||||
} else if prev_indent != 0 {
|
||||
line = format!("\n{}", line);
|
||||
}
|
||||
} else if is_list {
|
||||
line = format!("{}- {}", " ".repeat(indent), line);
|
||||
} else {
|
||||
line = format!("{}{}", " ".repeat(indent), line);
|
||||
}
|
||||
|
||||
line
|
||||
}
|
||||
|
||||
fn process_input(input: &str, writer: &mut std::io::BufWriter<File>) {
|
||||
let ignore_regex = Regex::new(IGNORE_LINE_PATTERN).unwrap();
|
||||
let list_regex = Regex::new(LIST_LINE_PATTERN).unwrap();
|
||||
let mut prev_indent = 0;
|
||||
let mut is_code_block = false;
|
||||
|
||||
for line in input.lines() {
|
||||
if ignore_regex.is_match(line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut indent = line
|
||||
.replace('\t', " ")
|
||||
.chars()
|
||||
.take_while(|&c| c == ' ')
|
||||
.count()
|
||||
/ 2;
|
||||
|
||||
let is_list = list_regex.is_match(line);
|
||||
|
||||
if !is_list && indent > 0 {
|
||||
indent -= 1;
|
||||
}
|
||||
|
||||
let processed_line = process_line(line, is_list, indent, prev_indent, &mut is_code_block);
|
||||
|
||||
writer
|
||||
.write_fmt(format_args!("{}\n", processed_line))
|
||||
.unwrap();
|
||||
|
||||
prev_indent = indent;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version)]
|
||||
struct Args {
|
||||
#[arg(short, long)]
|
||||
input: String,
|
||||
|
||||
#[arg(short, long)]
|
||||
output: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
if !Path::new(&args.input).join("logseq").exists() {
|
||||
eprintln!("The logseq directory does not exist.");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let input_assets = Path::new(&args.input).join("assets");
|
||||
let output_path = Path::new(&args.output);
|
||||
let output_assets = output_path.join("assets");
|
||||
|
||||
std::fs::create_dir_all(&output_assets).unwrap();
|
||||
|
||||
for entry in input_assets.read_dir().unwrap() {
|
||||
let entry = entry.unwrap();
|
||||
let path = entry.path();
|
||||
|
||||
if path.is_file() {
|
||||
let output_path = output_assets.join(path.file_name().unwrap());
|
||||
std::fs::copy(&path, &output_path).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
let input_journals = Path::new(&args.input).join("journals");
|
||||
let input_pages = Path::new(&args.input).join("pages");
|
||||
let input_journal_files = input_journals.read_dir().unwrap();
|
||||
let input_pages_files = input_pages.read_dir().unwrap();
|
||||
|
||||
for entry in input_journal_files {
|
||||
let entry = entry.unwrap();
|
||||
let path = entry.path();
|
||||
|
||||
if !path.is_file() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let name = path
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.replace("_", "-");
|
||||
|
||||
let output_file = File::create(output_path.join(name)).unwrap();
|
||||
let mut writer = std::io::BufWriter::new(output_file);
|
||||
let input = std::fs::read_to_string(&path).unwrap();
|
||||
process_input(&input, &mut writer);
|
||||
}
|
||||
|
||||
for entry in input_pages_files {
|
||||
let entry = entry.unwrap();
|
||||
let path = entry.path();
|
||||
|
||||
if path.is_file() {
|
||||
let input = std::fs::read_to_string(&path).unwrap();
|
||||
let name = path.file_name().unwrap();
|
||||
let output_file = File::create(output_path.join(name)).unwrap();
|
||||
let mut writer = std::io::BufWriter::new(output_file);
|
||||
process_input(&input, &mut writer);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue