Rename project to kindle2notes
This commit is contained in:
1 parent
15ff70b4c3
commit
432a1dc223
7 files changed
+110
-124
No files matched your search
+4
-16
@@ -1,12 +1,12 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
project(kindle2latex LANGUAGES CXX)
|
project(kindle2notes LANGUAGES CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
function(kindle2latex_enable_warnings target)
|
function(kindle2notes_enable_warnings target)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_options(${target} PRIVATE /W4)
|
target_compile_options(${target} PRIVATE /W4)
|
||||||
else()
|
else()
|
||||||
@@ -14,7 +14,7 @@ function(kindle2latex_enable_warnings target)
|
|||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
add_executable(kindle2latex_typefactory
|
add_executable(kindle2notes
|
||||||
typefactory/convertlatex.cpp
|
typefactory/convertlatex.cpp
|
||||||
typefactory/convertlatex.h
|
typefactory/convertlatex.h
|
||||||
typefactory/convertmarkdown.cpp
|
typefactory/convertmarkdown.cpp
|
||||||
@@ -24,16 +24,4 @@ add_executable(kindle2latex_typefactory
|
|||||||
typefactory/main.cpp
|
typefactory/main.cpp
|
||||||
typefactory/typefactory.h
|
typefactory/typefactory.h
|
||||||
)
|
)
|
||||||
set_target_properties(kindle2latex_typefactory PROPERTIES
|
kindle2notes_enable_warnings(kindle2notes)
|
||||||
OUTPUT_NAME kindle2latex-typefactory
|
|
||||||
)
|
|
||||||
kindle2latex_enable_warnings(kindle2latex_typefactory)
|
|
||||||
|
|
||||||
add_executable(kindle2latex_fsm
|
|
||||||
fsm/main.cpp
|
|
||||||
fsm/fsm.h
|
|
||||||
)
|
|
||||||
set_target_properties(kindle2latex_fsm PROPERTIES
|
|
||||||
OUTPUT_NAME kindle2latex-fsm
|
|
||||||
)
|
|
||||||
kindle2latex_enable_warnings(kindle2latex_fsm)
|
|
||||||
@@ -208,7 +208,7 @@ If you develop a new program, and you want it to be of the greatest possible use
|
|||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
|
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
kindle2latex
|
kindle2notes
|
||||||
Copyright (C) 2026 gpl
|
Copyright (C) 2026 gpl
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
@@ -221,7 +221,7 @@ Also add information on how to contact you by electronic and paper mail.
|
|||||||
|
|
||||||
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
|
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
kindle2latex Copyright (C) 2026 gpl
|
kindle2notes Copyright (C) 2026 gpl
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
|
This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +1,21 @@
|
|||||||
# Kindle Clippings → LaTeX Converter
|
# kindle2notes
|
||||||
|
|
||||||
A small console utility that converts Amazon Kindle *My Clippings* text exports into structured LaTeX.
|
`kindle2notes` is a small C++17 command-line utility that converts Amazon
|
||||||
|
Kindle `My Clippings.txt` exports into structured notes.
|
||||||
|
|
||||||
The tool parses Kindle highlights and groups them by book title, producing a LaTeX structure with:
|
Supported output formats:
|
||||||
|
|
||||||
* `\section{}` — per book
|
- LaTeX (`--type=latex`)
|
||||||
* `\subsection{}` — per highlight (metadata line)
|
- Markdown (`--type=md`)
|
||||||
* Highlight text — inserted as plain LaTeX content
|
|
||||||
* `\subsubsection{notes}` — placeholder for future comments
|
|
||||||
|
|
||||||
---
|
Highlights are grouped by book title while preserving the order in which
|
||||||
|
books first appear in the input file.
|
||||||
|
|
||||||
## Architecture
|
## Input format
|
||||||
|
|
||||||
This project demonstrates **two different parsing approaches** solving the same problem:
|
Each Kindle clipping is expected to have the following structure:
|
||||||
|
|
||||||
### 1️⃣ FSM-based parser
|
```text
|
||||||
|
|
||||||
Implemented using a template-based finite state machine (`fsm.h`).
|
|
||||||
|
|
||||||
Characteristics:
|
|
||||||
|
|
||||||
* Compile-time validated transitions
|
|
||||||
* Strong type safety
|
|
||||||
* Explicit state/event model
|
|
||||||
* Strict contract enforcement
|
|
||||||
|
|
||||||
This version is useful when:
|
|
||||||
|
|
||||||
* The input format is more complex
|
|
||||||
* You want compile-time guarantees for state transitions
|
|
||||||
* The parsing logic may grow over time
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2️⃣ TypeFactory-based parser
|
|
||||||
|
|
||||||
Implemented using a registration-based factory (`typefactory.h`).
|
|
||||||
|
|
||||||
Characteristics:
|
|
||||||
|
|
||||||
* Stage-driven pipeline
|
|
||||||
* One handler per parsing stage
|
|
||||||
* Runtime validation of handler registration
|
|
||||||
* No per-line allocations (handlers cached once)
|
|
||||||
|
|
||||||
This version is:
|
|
||||||
|
|
||||||
* Simpler
|
|
||||||
* More readable
|
|
||||||
* Easier to debug
|
|
||||||
* Well suited for linear, protocol-like formats
|
|
||||||
|
|
||||||
Both implementations produce identical LaTeX output.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Input Format
|
|
||||||
|
|
||||||
Expected input is a standard Kindle `My Clippings.txt` export.
|
|
||||||
|
|
||||||
Each clipping block follows this structure:
|
|
||||||
|
|
||||||
```
|
|
||||||
Book Title
|
Book Title
|
||||||
- Your Highlight on Location 123-125 | Added on ...
|
- Your Highlight on Location 123-125 | Added on ...
|
||||||
|
|
||||||
@@ -71,65 +24,106 @@ Highlighted text line 2
|
|||||||
==========
|
==========
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
The final clipping is processed even when the file does not end with the
|
||||||
|
`==========` separator. Incomplete clipping blocks are ignored.
|
||||||
|
|
||||||
## Output Format
|
## Output formats
|
||||||
|
|
||||||
Generated LaTeX structure:
|
### LaTeX
|
||||||
|
|
||||||
|
Books become sections, clipping metadata becomes subsections, and every
|
||||||
|
highlight receives an empty notes subsection:
|
||||||
|
|
||||||
```latex
|
```latex
|
||||||
\section{Book Title}
|
\section {Book Title}
|
||||||
|
\subsection {- Your Highlight on Location 123-125 | Added on ...}
|
||||||
\subsection{- Your Highlight on Location 123-125 | Added on ...}
|
|
||||||
Highlighted text line 1
|
Highlighted text line 1
|
||||||
Highlighted text line 2
|
Highlighted text line 2
|
||||||
\subsubsection{notes}
|
\subsubsection{notes}
|
||||||
```
|
```
|
||||||
|
|
||||||
Highlights are grouped by book title.
|
LaTeX special characters are escaped automatically.
|
||||||
|
|
||||||
---
|
### Markdown
|
||||||
|
|
||||||
|
Books and clipping metadata become headings. Highlight text is emitted as a
|
||||||
|
Markdown block quote, followed by an empty notes heading:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Book Title
|
||||||
|
|
||||||
|
## - Your Highlight on Location 123-125 | Added on ...
|
||||||
|
|
||||||
|
> Highlighted text line 1
|
||||||
|
> Highlighted text line 2
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
```
|
||||||
|
|
||||||
|
Empty lines inside highlights are preserved as `>` lines, and Markdown syntax
|
||||||
|
characters are escaped automatically.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
Input parsing is implemented as a stage-driven pipeline with one handler for
|
||||||
|
each stage: title, metadata, and body. Handlers are registered and created
|
||||||
|
through the generic `TypeFactory` template, then cached for reuse while the
|
||||||
|
input is read.
|
||||||
|
|
||||||
|
Output generation uses a common abstract `Converter` interface. Concrete
|
||||||
|
converters are registered in another `TypeFactory` under their command-line
|
||||||
|
type names. The selected converter is created at runtime and invoked through
|
||||||
|
the common virtual `save()` method. Adding a new output format requires a new
|
||||||
|
`Converter` subclass and a corresponding factory registration.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
Requires a C++17-compatible compiler.
|
The project has no Qt dependency. It requires a C++17 compiler and CMake 3.16
|
||||||
|
or newer.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
g++ -std=gnu++17 -Wall -Wextra -O2 -o kindle2latex main.cpp
|
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build build --parallel
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
The resulting executable is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
build/kindle2notes
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
Generate LaTeX:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./kindle2latex --input input.txt --output output.tex
|
./build/kindle2notes \
|
||||||
|
--input "My Clippings.txt" \
|
||||||
|
--output notes.tex \
|
||||||
|
--type=latex
|
||||||
```
|
```
|
||||||
|
|
||||||
Arguments:
|
Generate Markdown:
|
||||||
|
|
||||||
| Argument | Description |
|
```bash
|
||||||
| ---------- | ----------------------------- |
|
./build/kindle2notes \
|
||||||
| `--input` | Path to Kindle clippings file |
|
--input "My Clippings.txt" \
|
||||||
| `--output` | Path to generated LaTeX file |
|
--output notes.md \
|
||||||
|
--type=md
|
||||||
|
```
|
||||||
|
|
||||||
---
|
Short options are also available:
|
||||||
|
|
||||||
## Design Notes
|
```bash
|
||||||
|
./build/kindle2notes -i input.txt -o notes.md -t md
|
||||||
|
```
|
||||||
|
|
||||||
* No dynamic allocations per input line (handlers are cached).
|
| Argument | Short form | Description |
|
||||||
* Order of books is preserved as in the original file.
|
| --- | --- | --- |
|
||||||
* LaTeX special characters are escaped automatically.
|
| `--input` | `-i` | Path to the Kindle clippings file |
|
||||||
* Incomplete clipping blocks are safely ignored.
|
| `--output` | `-o` | Path to the generated file |
|
||||||
* The final block is flushed even if the file does not end with `==========`.
|
| `--type` | `-t` | Output format: `latex` or `md` |
|
||||||
|
| `--help` | `-h` | Show usage information |
|
||||||
|
|
||||||
---
|
If an unsupported output type is requested, the program prints the list of
|
||||||
|
available formats and exits without creating an output file.
|
||||||
## Why Two Implementations?
|
|
||||||
|
|
||||||
This repository intentionally keeps two different parsing styles:
|
|
||||||
|
|
||||||
* The FSM version demonstrates strict compile-time state control.
|
|
||||||
* The TypeFactory version demonstrates a clean, extensible runtime pipeline.
|
|
||||||
|
|
||||||
The goal is architectural exploration and comparison, not just solving the parsing task.
|
|
||||||
@@ -11,18 +11,11 @@ static bool markdown_needs_escape (char ch) {
|
|||||||
case '`':
|
case '`':
|
||||||
case '*':
|
case '*':
|
||||||
case '_':
|
case '_':
|
||||||
case '{':
|
|
||||||
case '}':
|
|
||||||
case '[':
|
case '[':
|
||||||
case ']':
|
case ']':
|
||||||
case '<':
|
case '<':
|
||||||
case '>':
|
case '>':
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
case '#':
|
case '#':
|
||||||
case '+':
|
|
||||||
case '-':
|
|
||||||
case '.':
|
|
||||||
case '!':
|
case '!':
|
||||||
case '|':
|
case '|':
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
TEMPLATE = app
|
|
||||||
CONFIG += console c++17
|
|
||||||
CONFIG -= app_bundle
|
|
||||||
CONFIG -= qt
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
main.cpp
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
TARGET = kindle2notes
|
||||||
|
CONFIG += console c++17
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
CONFIG -= qt
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
convertlatex.cpp \
|
||||||
|
convertmarkdown.cpp \
|
||||||
|
converter.cpp \
|
||||||
|
main.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
convertlatex.h \
|
||||||
|
convertmarkdown.h \
|
||||||
|
converter.h \
|
||||||
|
typefactory.h
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
TARGET = kindle2notes
|
||||||
CONFIG += console c++17
|
CONFIG += console c++17
|
||||||
CONFIG -= app_bundle
|
CONFIG -= app_bundle
|
||||||
CONFIG -= qt
|
CONFIG -= qt
|
||||||
|
|||||||
Reference in new issue
Block a user