Bookit is a small command-line tool for managing personal PDF "workspaces" on your filesystem. It lets you initialize library directories, register and switch between them, and add, list, open, remove, and update PDF books with associated metadata.
Highlights: C++17 CLI, filesystem-heavy operations, JSON-based metadata, robust error handling.
- Language: C++17
- Build system: CMake (minimum 3.16)
- Standard library:
std::filesystem,<algorithm>,<optional>, etc. - JSON library: nlohmann/json (header-only, vendored in
third_party/)
High-level components:
src/main.cpp: Entry point; parses CLI arguments viaCommandParser, then delegates toLibraryManager.CommandParser: Parsesargc/argvinto a command type (CommandInfo::Type), a path argument, and an option map.CommandInfo: Defines command and option enums/names and prints help and error messages.LibraryManager: Orchestrates execution of commands usingCoreandWorkspaces.Core: Implements book-level operations inside a workspace (add, remove, list, open, update metadata).Workspaces: Manages theworkspaces.jsonconfiguration next to the executable and tracks known workspaces and the current one.
Data layout:
- Each workspace directory contains a hidden
.bookit/metadata.jsonfile describing the workspace version and the list of books (name, author, year, isbn, category). - A global
workspaces.jsonnext to thebookitbinary tracks:current: the current workspace path (string or empty).workspaces: an array of workspace paths.
- A C++17-capable compiler (e.g.
g++ >= 9,clang++ >= 10). - CMake 3.16+.
- A POSIX-like environment (Linux is the primary target. uses
/proc/self/exeto locateworkspaces.jsonandxdg-openutility to open PDFs using the user's preferred application).
From the project root:
mkdir -p build
cd build
cmake -S .. -B .
cmake --build .The resulting executable will be placed under:
build/bin/bookit
You can then either add build/bin to your PATH or invoke the tool directly:
./bin/bookit --helpbookit-cli/
├── CMakeLists.txt # CMake build configuration
├── include/ # Public headers
│ ├── Books.h
│ ├── Command.h
│ ├── CommandInfo.h
│ ├── CommandParser.h
│ ├── Core.h
│ ├── LibraryManager.h
│ └── Workspaces.h
├── src/ # Implementation files
│ ├── Command.cpp
│ ├── CommandInfo.cpp
│ ├── CommandParser.cpp
│ ├── Core.cpp
│ ├── LibraryManager.cpp
│ ├── Workspaces.cpp
│ └── main.cpp
├── third_party/
│ └── nlohmann/json.hpp # Header-only JSON library
└── README.md # This file
Within a workspace directory (chosen by you):
<workspace-root>/
├── .bookit/
│ └── metadata.json # Workspace metadata and book list
├── some-book.pdf
└── another-book.pdf
-
Workspace management
init <directory>: Initialize a new workspace (creates.bookit/metadata.json).listws: List all tracked workspaces and show the current workspace.switchws <directory>: Switch the current workspace to an existing entry.removews <directory>: Unregister a workspace (leaves the actual directory and PDFs on disk; prints a manualrm -rhint).
-
Book management (operate on the current workspace):
addbook <path/to/book.pdf>: Copies the PDF into the workspace and adds metadata.removebook <book.pdf>: Deletes the PDF from the workspace and removes its metadata entry.updatebook <book.pdf>: Updates existing metadata fields for a book.listbooks: Prints all books in the workspace in a tabular line format.openbook <book.pdf>: Opens a book using the system viewer (e.g.xdg-open).
-
Metadata options for
addbookandupdatebook:--author <name>--year <year>--isbn <value>--category <label>
Robust error handling:
- Validates that workspaces and metadata files exist and are well-formed.
- Checks that book files are valid PDFs (via magic
%PDFheader) before import. - Ensures consistency between metadata and actual files in the workspace.
Display help:
bookit --helpInitialize and use a workspace:
# Initialize a workspace directory
bookit init /path/to/my-workspace
# Switch to it (if not already current)
bookit switchws /path/to/my-workspace
# Add a book with metadata
bookit addbook /path/to/some-book.pdf \
--author "Some Author" \
--year "2024" \
--isbn "978-3-16-148410-0" \
--category "Programming"
# List all books in the current workspace
bookit listbooks
# Open a book using the system viewer
bookit openbook some-book.pdf
# Update metadata for an existing book
bookit updatebook some-book.pdf --author "New Author"
# Remove a book
bookit removebook some-book.pdfManaging workspaces:
# List tracked workspaces
bookit listws
# Remove a tracked workspace (does NOT delete files)
bookit removews /path/to/my-workspaceDuring development, you typically:
- Edit code under
src/andinclude/. - Reconfigure if needed with CMake.
- Rebuild the
bookitbinary:
cd build
cmake --build .- C++17, with warnings enabled:
-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wshadow -pedantic-errors. - Consistent use of
std::filesystemfor path handling. - Error handling via
std::error_codewhere applicable (e.g. filesystem operations) and clearstd::cerrmessages. - JSON structures represented with
nlohmann::jsonand validated before use (e.g. checking arrays and keys). - Helper functions placed in anonymous namespaces in
.cppfiles to avoid leaking internal symbols.
Contributions are welcome but not expected. Feel free to open issues or pull requests. A lightweight flow is enough:
- Fork the repository and create a feature branch.
- Make changes in
src/andinclude/following the existing style (warning-free build, modern C++17). - Rebuild and sanity-check core commands (e.g.
bookit --help,init,addbook,listbooks). - Open a pull request with a short description of what changed and why.
This project is licensed under the MIT License. Please refer to that file for the full license text and terms under which Bookit is distributed.
Status: Maintained as a personal project. Stable for everyday use, with room for future enhancements (e.g. search/filtering, more metadata fields).