- Refactored code to return text

- This is to make sending data to the TUI easier
This commit is contained in:
Daniel Jones 2023-07-20 10:28:40 -05:00
parent 305b74abd3
commit 2fe2421e6d
9 changed files with 1017 additions and 995 deletions

View File

@ -1,22 +1,22 @@
name: Rust name: Rust
on: on:
push: push:
branches: [ "master" ] branches: [ "master" ]
pull_request: pull_request:
branches: [ "master" ] branches: [ "master" ]
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Build - name: Build
run: cargo build --verbose run: cargo build --verbose
- name: Run tests - name: Run tests
run: cargo test --verbose run: cargo test --verbose

22
.gitignore vendored
View File

@ -1,11 +1,11 @@
# Generated by Cargo # Generated by Cargo
# will have compiled files and executables # will have compiled files and executables
/target/ /target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock Cargo.lock
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk
*.epub *.epub

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -1,48 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="AutoImportSettings"> <component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="CMakeSettings"> <component name="CMakeSettings">
<configurations> <configurations>
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" /> <configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" />
</configurations> </configurations>
</component> </component>
<component name="CargoProjects"> <component name="CargoProjects">
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" /> <cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="81820af5-b0ad-4ac7-a939-e3db68fc7214" name="Changes" comment="- Can now format HTML&#10;- No longer returns to main.rs. Main function in html_module.rs now reads to console locally."> <list default="true" id="81820af5-b0ad-4ac7-a939-e3db68fc7214" name="Changes" comment="- Can now format HTML&#10;- No longer returns to main.rs. Main function in html_module.rs now reads to console locally.">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.rs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/html_module.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/html_module.rs" afterDir="false" />
</list> <change beforePath="$PROJECT_DIR$/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.rs" afterDir="false" />
<option name="SHOW_DIALOG" value="false" /> </list>
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="LAST_RESOLUTION" value="IGNORE" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
</component> <option name="LAST_RESOLUTION" value="IGNORE" />
<component name="ClangdSettings"> </component>
<option name="formatViaClangd" value="false" /> <component name="ClangdSettings">
</component> <option name="formatViaClangd" value="false" />
<component name="Git.Settings"> </component>
<option name="RECENT_BRANCH_BY_REPOSITORY"> <component name="Git.Settings">
<map> <option name="RECENT_BRANCH_BY_REPOSITORY">
<entry key="$PROJECT_DIR$" value="master" /> <map>
</map> <entry key="$PROJECT_DIR$" value="master" />
</option> </map>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> </option>
</component> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
<component name="MacroExpansionManager"> </component>
<option name="directoryName" value="3emh3loa" /> <component name="MacroExpansionManager">
</component> <option name="directoryName" value="3emh3loa" />
<component name="MarkdownSettingsMigration"> </component>
<option name="stateVersion" value="1" /> <component name="MarkdownSettingsMigration">
</component> <option name="stateVersion" value="1" />
<component name="ProjectId" id="2PqGkAwNc4bG190Io9DyS4FEdlC" /> </component>
<component name="ProjectViewState"> <component name="ProjectId" id="2PqGkAwNc4bG190Io9DyS4FEdlC" />
<option name="hideEmptyMiddlePackages" value="true" /> <component name="ProjectViewState">
<option name="showLibraryContents" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
</component> <option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent"><![CDATA[{
"keyToString": { "keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true", "RunOnceActivity.OpenProjectViewOnStart": "true",
@ -59,125 +60,128 @@
"node.js.selected.package.eslint": "(autodetect)", "node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)", "node.js.selected.package.tslint": "(autodetect)",
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true", "org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
"org.rust.disableDetachedFileInspectionD:/bibliofile/src/html_module.rs": "true",
"org.rust.disableDetachedFileInspectionD:/bibliofile/src/main.rs": "true",
"settings.editor.selected.configurable": "org.jetbrains.plugins.github.ui.GithubSettingsConfigurable", "settings.editor.selected.configurable": "org.jetbrains.plugins.github.ui.GithubSettingsConfigurable",
"vue.rearranger.settings.migration": "true" "vue.rearranger.settings.migration": "true"
} }
}]]></component> }]]></component>
<component name="RunManager" selected="Cargo.Check"> <component name="RunManager" selected="Cargo.Check">
<configuration name="Check" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true"> <configuration name="Check" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true">
<option name="command" value="check" /> <option name="command" value="check" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" /> <option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="false" /> <option name="emulateTerminal" value="false" />
<option name="channel" value="DEFAULT" /> <option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" /> <option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" /> <option name="allFeatures" value="false" />
<option name="withSudo" value="false" /> <option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" /> <option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" /> <option name="backtrace" value="SHORT" />
<envs /> <envs />
<option name="isRedirectInput" value="false" /> <option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" /> <option name="redirectInputPath" value="" />
<method v="2"> <method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" /> <option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method> </method>
</configuration> </configuration>
<configuration name="Run" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true"> <configuration name="Run" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true">
<option name="command" value="run pg2680.epub" /> <option name="command" value="run pg2680.epub" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" /> <option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="emulateTerminal" value="false" /> <option name="emulateTerminal" value="false" />
<option name="channel" value="DEFAULT" /> <option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" /> <option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" /> <option name="allFeatures" value="false" />
<option name="withSudo" value="false" /> <option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" /> <option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" /> <option name="backtrace" value="SHORT" />
<envs /> <envs />
<option name="isRedirectInput" value="false" /> <option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" /> <option name="redirectInputPath" value="" />
<method v="2"> <method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" /> <option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method> </method>
</configuration> </configuration>
<list> <list>
<item itemvalue="Cargo.Run" /> <item itemvalue="Cargo.Run" />
<item itemvalue="Cargo.Check" /> <item itemvalue="Cargo.Check" />
</list> </list>
</component> </component>
<component name="RustProjectSettings"> <component name="RustProjectSettings">
<option name="toolchainHomeDirectory" value="//wsl$/Ubuntu-22.04/home/jonesd/.cargo/bin" /> <option name="toolchainHomeDirectory" value="//wsl$/Ubuntu-22.04/home/jonesd/.cargo/bin" />
</component> </component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" /> <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager"> <component name="TaskManager">
<task active="true" id="Default" summary="Default task"> <task active="true" id="Default" summary="Default task">
<changelist id="81820af5-b0ad-4ac7-a939-e3db68fc7214" name="Changes" comment="" /> <changelist id="81820af5-b0ad-4ac7-a939-e3db68fc7214" name="Changes" comment="" />
<created>1684177338227</created> <created>1684177338227</created>
<option name="number" value="Default" /> <option name="number" value="Default" />
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1684177338227</updated> <updated>1684177338227</updated>
<workItem from="1684177339283" duration="296000" /> <workItem from="1684177339283" duration="296000" />
<workItem from="1684180154545" duration="927000" /> <workItem from="1684180154545" duration="927000" />
<workItem from="1684181684374" duration="176000" /> <workItem from="1684181684374" duration="176000" />
<workItem from="1684345543022" duration="781000" /> <workItem from="1684345543022" duration="781000" />
<workItem from="1687970763540" duration="4628000" /> <workItem from="1687970763540" duration="4628000" />
<workItem from="1689824866342" duration="40000" /> <workItem from="1689824866342" duration="40000" />
</task> <workItem from="1689861266305" duration="5017000" />
<task id="LOCAL-00001" summary="Commit to scraper_framework branch&#10;&#10; - changing framework from Soup to Scraper&#10; - removed ncurses library. Will use different library instead."> </task>
<created>1687972565061</created> <task id="LOCAL-00001" summary="Commit to scraper_framework branch&#10;&#10; - changing framework from Soup to Scraper&#10; - removed ncurses library. Will use different library instead.">
<option name="number" value="00001" /> <created>1687972565061</created>
<option name="presentableId" value="LOCAL-00001" /> <option name="number" value="00001" />
<option name="project" value="LOCAL" /> <option name="presentableId" value="LOCAL-00001" />
<updated>1687972565061</updated> <option name="project" value="LOCAL" />
</task> <updated>1687972565061</updated>
<task id="LOCAL-00002" summary="Commit to scraper_framework branch&#10;&#10; - changing framework from Soup to Scraper&#10; - removed ncurses library. Will use different library instead."> </task>
<created>1687972590786</created> <task id="LOCAL-00002" summary="Commit to scraper_framework branch&#10;&#10; - changing framework from Soup to Scraper&#10; - removed ncurses library. Will use different library instead.">
<option name="number" value="00002" /> <created>1687972590786</created>
<option name="presentableId" value="LOCAL-00002" /> <option name="number" value="00002" />
<option name="project" value="LOCAL" /> <option name="presentableId" value="LOCAL-00002" />
<updated>1687972590786</updated> <option name="project" value="LOCAL" />
</task> <updated>1687972590786</updated>
<task id="LOCAL-00003" summary="- Can now format HTML&#10;- No longer returns to main.rs. Main function in html_module.rs now reads to console locally."> </task>
<created>1687974796970</created> <task id="LOCAL-00003" summary="- Can now format HTML&#10;- No longer returns to main.rs. Main function in html_module.rs now reads to console locally.">
<option name="number" value="00003" /> <created>1687974796970</created>
<option name="presentableId" value="LOCAL-00003" /> <option name="number" value="00003" />
<option name="project" value="LOCAL" /> <option name="presentableId" value="LOCAL-00003" />
<updated>1687974796970</updated> <option name="project" value="LOCAL" />
</task> <updated>1687974796970</updated>
<option name="localTasksCounter" value="4" /> </task>
<servers /> <option name="localTasksCounter" value="4" />
</component> <servers />
<component name="TypeScriptGeneratedFilesManager"> </component>
<option name="version" value="3" /> <component name="TypeScriptGeneratedFilesManager">
</component> <option name="version" value="3" />
<component name="Vcs.Log.Tabs.Properties"> </component>
<option name="TAB_STATES"> <component name="Vcs.Log.Tabs.Properties">
<map> <option name="TAB_STATES">
<entry key="MAIN"> <map>
<value> <entry key="MAIN">
<State> <value>
<option name="FILTERS"> <State>
<map> <option name="FILTERS">
<entry key="branch"> <map>
<value> <entry key="branch">
<list> <value>
<option value="scraper_framework" /> <list>
</list> <option value="scraper_framework" />
</value> </list>
</entry> </value>
</map> </entry>
</option> </map>
</State> </option>
</value> </State>
</entry> </value>
</map> </entry>
</option> </map>
</component> </option>
<component name="VcsManagerConfiguration"> </component>
<MESSAGE value="Commit to scraper_framework branch&#10;&#10; - changing framework from Soup to Scraper&#10; - removed ncurses library. Will use different library instead." /> <component name="VcsManagerConfiguration">
<MESSAGE value="- Can now format HTML&#10;- No longer returns to main.rs. Main function in html_module.rs now reads to console locally." /> <MESSAGE value="Commit to scraper_framework branch&#10;&#10; - changing framework from Soup to Scraper&#10; - removed ncurses library. Will use different library instead." />
<option name="LAST_COMMIT_MESSAGE" value="- Can now format HTML&#10;- No longer returns to main.rs. Main function in html_module.rs now reads to console locally." /> <MESSAGE value="- Can now format HTML&#10;- No longer returns to main.rs. Main function in html_module.rs now reads to console locally." />
</component> <option name="LAST_COMMIT_MESSAGE" value="- Can now format HTML&#10;- No longer returns to main.rs. Main function in html_module.rs now reads to console locally." />
<component name="XSLT-Support.FileAssociations.UIState"> </component>
<expand /> <component name="XSLT-Support.FileAssociations.UIState">
<select /> <expand />
</component> <select />
</component>
</project> </project>

View File

@ -9,4 +9,5 @@ edition = "2021"
epub = "2.0.0" epub = "2.0.0"
ncurses = "5.101.0" ncurses = "5.101.0"
scraper = "0.17.1" scraper = "0.17.1"
tuikit = "0.5.0"

1348
LICENSE

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
# Bibliofile # Bibliofile
### A TUI-based ebook reader that hopefully doesn't suck! ### A TUI-based ebook reader that hopefully doesn't suck!
A long long time ago, I was in college. I frequently bought the ebook versions of my textbooks, but to my dismay...most ebook readers sucked. The user interface was complicated, dark mode was unavailable for most readers until I neared graduation, dark mode usually looked terrible even if it was available, etc. I hope to change that. What better dark mode that running it on the TUI? What better way to make a simple UI than to design one myself that *I* like? A long long time ago, I was in college. I frequently bought the ebook versions of my textbooks, but to my dismay...most ebook readers sucked. The user interface was complicated, dark mode was unavailable for most readers until I neared graduation, dark mode usually looked terrible even if it was available, etc. I hope to change that. What better dark mode that running it on the TUI? What better way to make a simple UI than to design one myself that *I* like?
This is very much a personal project. Rust isn't exactly used for big companies besides Mozilla just yet, and progress is slow-going due to my personal and work commitments. Still, when it is done, I will attempt to release it on several popular repositories such as Flatpack so that others can use it. This is very much a personal project. Rust isn't exactly used for big companies besides Mozilla just yet, and progress is slow-going due to my personal and work commitments. Still, when it is done, I will attempt to release it on several popular repositories such as Flatpack so that others can use it.
Feel free to check up on progress on my blog, www.whoisthisjoker.com. I post there periodically to talk about what direction I want the project to go. Feel free to check up on progress on my blog, www.whoisthisjoker.com. I post there periodically to talk about what direction I want the project to go.

View File

@ -1,25 +1,36 @@
/* /*
Program: Bibliofile Program: Bibliofile
Purpose: This class is meant to process and return HTML formatted text as strings. Purpose: This class is meant to process and return HTML formatted text as strings.
Last edited: 6/28/23 Last edited: 7/20/23
*/ */
use scraper::{Html, Selector};
use scraper::{Html, Selector};
pub fn main(content: String){
pub fn main(content: String) -> String{
let str_content = Html::parse_document(&content);
let str_content = Html::parse_document(&content);
//Selector is HTML tag. Can be <br> or <p> or anything else. To parse entire page, set selector to <html>
let selector = Selector::parse("html").unwrap(); //Selector is HTML tag. Can be <br> or <p> or anything else. To parse entire page, set selector to <html>
let unwrapped_page = str_content.select(&selector).next().unwrap(); let selector = Selector::parse("html").unwrap();
let page = unwrapped_page.text().collect::<Vec<_>>(); let unwrapped_page = str_content.select(&selector).next().unwrap();
let page = unwrapped_page.text().collect::<Vec<_>>();
//every line in document is an entry into the vector. For loop iterates through every entry and displays it. let mut text = String::new();
for i in 0..page.len() { //every line in document is an entry into the vector. For loop iterates through every entry and displays it.
println!("{}", page[i]); for i in 0..page.len() {
}
if i < page.len() {
text = text + page[i];
}
if i == page.len(){
text = text + page[i];
return text.to_string();
}
}
return text.to_string();
} }

View File

@ -1,93 +1,93 @@
/* /*
Program: Bibliofile Program: Bibliofile
Language: Rustc 1.70.0 Language: Rustc 1.70.0
ide: CLion ide: CLion
Operating system: Fedora 38/WSL Operating system: Fedora 38/WSL
Purpose: ncurses based ereader and library manager for Linux terminal environments. Purpose: TUI-based ereader and library manager for Linux terminal environments.
Last edited: 6/28/23 Last edited: 7/20/23
*/ */
//this is a test change to see if gitea is accepting pushes. //this is a test change to see if gitea is accepting pushes.
mod html_module; mod html_module;
use epub::doc::EpubDoc; //library for navigating epubs use epub::doc::EpubDoc; //library for navigating epubs
use std::env; use std::env;
use std::process::exit; use std::process::exit;
//initial function. Reads the ebook passed by argument. //initial function. Reads the ebook passed by argument.
//TODO: add visual library to pull up ebooks. //TODO: add visual library to pull up ebooks.
fn main() { fn main() {
if env::args().len() == 1 { if env::args().len() == 1 {
println!("you need to enter a book. Closing program."); println!("you need to enter a book. Closing program.");
} }
else { else {
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let filename = &args[1]; let filename = &args[1];
epub_func(filename); epub_func(filename);
} }
} }
//parses epub files //parses epub files
fn epub_func(epub_file: &str){ fn epub_func(epub_file: &str){
let doc = EpubDoc::new(&epub_file); let doc = EpubDoc::new(&epub_file);
assert!(doc.is_ok()); assert!(doc.is_ok());
let mut doc = doc.unwrap(); let mut doc = doc.unwrap();
let mut page_num = 1; let mut page_num = 1;
let is_reading = true; let is_reading = true;
while is_reading == true { while is_reading == true {
let mut next_or_last = String::new(); let mut next_or_last = String::new();
doc.set_current_page(page_num); doc.set_current_page(page_num);
let content = doc.get_current_str(); let content = doc.get_current_str();
let str_content = content.unwrap(); let str_content = content.unwrap();
html_module::main(str_content.0); let text = html_module::main(str_content.0);
println!("{}", text);
let input_size = std::io::stdin().read_line(&mut next_or_last); let input_size = std::io::stdin().read_line(&mut next_or_last);
let input_size_len = input_size.unwrap() - 1; let input_size_len = input_size.unwrap() - 1;
if input_size_len == 1{ if input_size_len == 1{
/* /*
Was not sure how to compare string to input from .read_line Was not sure how to compare string to input from .read_line
Instead, I felt that it would be easier to convert it to bytes and Instead, I felt that it would be easier to convert it to bytes and
compare the ASCII values. compare the ASCII values.
*/ */
let compare = next_or_last.as_bytes(); let compare = next_or_last.as_bytes();
//If user presses n(for next) goes forward one page. //If user presses n(for next) goes forward one page.
if compare[0] == 110 { if compare[0] == 110 {
page_num = page_num + 1; page_num = page_num + 1;
} }
//if user presses b, goes back one page. //if user presses b, goes back one page.
else if compare[0] == 98 { else if compare[0] == 98 {
//if page number equals one then you are at the beginning of the book. //if page number equals one then you are at the beginning of the book.
if page_num == 1 { if page_num == 1 {
println!("at beginning of book."); println!("at beginning of book.");
} }
else { else {
page_num = page_num - 1; page_num = page_num - 1;
} }
} }
//If user presses q(for quit), exits with status code of 0. //If user presses q(for quit), exits with status code of 0.
else if compare[0] == 113 { else if compare[0] == 113 {
println!("quitting..."); println!("quitting...");
exit(0); exit(0);
} }
else { else {
println!("did not understand command."); println!("did not understand command.");
} }
} }
else { else {
println!("Do not understand input. Try again."); println!("Do not understand input. Try again.");
} }
} }
} }