mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-01-30 13:04:13 +00:00
implement separated mods for tags
This commit is contained in:
parent
9e9b40e3ac
commit
ab0fa8fb14
@ -1,4 +1,5 @@
|
|||||||
mod parser;
|
mod parser;
|
||||||
|
mod tag;
|
||||||
mod widget;
|
mod widget;
|
||||||
|
|
||||||
use parser::code::Code;
|
use parser::code::Code;
|
||||||
@ -6,14 +7,13 @@ use parser::header::Header;
|
|||||||
use parser::link::Link;
|
use parser::link::Link;
|
||||||
use parser::list::List;
|
use parser::list::List;
|
||||||
use parser::quote::Quote;
|
use parser::quote::Quote;
|
||||||
|
use tag::Tag;
|
||||||
use widget::Widget;
|
use widget::Widget;
|
||||||
|
|
||||||
use adw::StyleManager;
|
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gdk::{BUTTON_MIDDLE, BUTTON_PRIMARY},
|
gdk::{BUTTON_MIDDLE, BUTTON_PRIMARY},
|
||||||
gio::{AppInfo, AppLaunchContext, SimpleAction},
|
gio::{AppInfo, AppLaunchContext, SimpleAction},
|
||||||
glib::{GString, TimeZone, Uri},
|
glib::{GString, TimeZone, Uri},
|
||||||
pango::Style,
|
|
||||||
prelude::{ActionExt, TextBufferExt, TextBufferExtManual, TextViewExt, ToVariant, WidgetExt},
|
prelude::{ActionExt, TextBufferExt, TextBufferExtManual, TextViewExt, ToVariant, WidgetExt},
|
||||||
EventControllerMotion, GestureClick, TextBuffer, TextTag, TextView, TextWindowType, WrapMode,
|
EventControllerMotion, GestureClick, TextBuffer, TextTag, TextView, TextWindowType, WrapMode,
|
||||||
};
|
};
|
||||||
@ -37,33 +37,23 @@ impl Reader {
|
|||||||
let mut title = None;
|
let mut title = None;
|
||||||
|
|
||||||
// Init HashMap storage for event controllers
|
// Init HashMap storage for event controllers
|
||||||
let mut links: HashMap<TextTag, Uri> = HashMap::new();
|
let mut links: HashMap<&TextTag, Uri> = HashMap::new();
|
||||||
|
|
||||||
// Init system palette
|
|
||||||
let style = StyleManager::default();
|
|
||||||
|
|
||||||
// Init new text buffer
|
|
||||||
let buffer = TextBuffer::new(None);
|
|
||||||
|
|
||||||
// Init multiline code builder features
|
// Init multiline code builder features
|
||||||
let mut multiline = None;
|
let mut multiline = None;
|
||||||
|
|
||||||
|
// Init tags
|
||||||
|
let tag = Tag::new();
|
||||||
|
|
||||||
|
// Init new text buffer
|
||||||
|
let buffer = TextBuffer::new(Some(tag.gobject()));
|
||||||
|
|
||||||
// Parse gemtext lines
|
// Parse gemtext lines
|
||||||
for line in gemtext.lines() {
|
for line in gemtext.lines() {
|
||||||
// Is inline code
|
// Is inline code
|
||||||
if let Some(code) = Code::inline_from(line) {
|
if let Some(code) = Code::inline_from(line) {
|
||||||
// Build tag from level parsed
|
|
||||||
let tag = TextTag::builder()
|
|
||||||
.family("monospace")
|
|
||||||
.scale(0.8)
|
|
||||||
.wrap_mode(WrapMode::None)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Register tag in buffer
|
|
||||||
buffer.tag_table().add(&tag);
|
|
||||||
|
|
||||||
// Append value to buffer
|
// Append value to buffer
|
||||||
buffer.insert_with_tags(&mut buffer.end_iter(), code.value.as_str(), &[&tag]);
|
buffer.insert_with_tags(&mut buffer.end_iter(), code.value.as_str(), &[tag.code()]);
|
||||||
buffer.insert(&mut buffer.end_iter(), "\n");
|
buffer.insert(&mut buffer.end_iter(), "\n");
|
||||||
|
|
||||||
// Skip other actions for this line
|
// Skip other actions for this line
|
||||||
@ -89,38 +79,20 @@ impl Reader {
|
|||||||
if this.completed {
|
if this.completed {
|
||||||
// Is alt provided
|
// Is alt provided
|
||||||
if let Some(alt) = &this.alt {
|
if let Some(alt) = &this.alt {
|
||||||
// Build tag for code alt description
|
|
||||||
let tag = TextTag::builder()
|
|
||||||
.pixels_above_lines(4)
|
|
||||||
.pixels_below_lines(8)
|
|
||||||
.weight(500)
|
|
||||||
.wrap_mode(WrapMode::None)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Register tag in buffer
|
|
||||||
buffer.tag_table().add(&tag);
|
|
||||||
|
|
||||||
// Insert alt value to the main buffer
|
// Insert alt value to the main buffer
|
||||||
buffer.insert_with_tags(&mut buffer.end_iter(), alt.as_str(), &[&tag]);
|
buffer.insert_with_tags(
|
||||||
|
&mut buffer.end_iter(),
|
||||||
|
alt.as_str(),
|
||||||
|
&[tag.title()],
|
||||||
|
);
|
||||||
buffer.insert(&mut buffer.end_iter(), "\n");
|
buffer.insert(&mut buffer.end_iter(), "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build tag container for multiline code result
|
|
||||||
let tag = TextTag::builder()
|
|
||||||
.family("monospace") // @TODO does not work
|
|
||||||
.left_margin(28)
|
|
||||||
.scale(0.8)
|
|
||||||
.wrap_mode(WrapMode::None)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Register tag in buffer
|
|
||||||
buffer.tag_table().add(&tag);
|
|
||||||
|
|
||||||
// Insert multiline code buffer into main buffer
|
// Insert multiline code buffer into main buffer
|
||||||
buffer.insert_with_tags(
|
buffer.insert_with_tags(
|
||||||
&mut buffer.end_iter(),
|
&mut buffer.end_iter(),
|
||||||
&this.buffer.join("\n"),
|
&this.buffer.join("\n"),
|
||||||
&[&tag],
|
&[tag.code()],
|
||||||
);
|
);
|
||||||
|
|
||||||
buffer.insert(&mut buffer.end_iter(), "\n");
|
buffer.insert(&mut buffer.end_iter(), "\n");
|
||||||
@ -136,33 +108,16 @@ impl Reader {
|
|||||||
|
|
||||||
// Is header
|
// Is header
|
||||||
if let Some(header) = Header::from(line) {
|
if let Some(header) = Header::from(line) {
|
||||||
// Build tag from level parsed
|
|
||||||
let tag = match header.level {
|
|
||||||
parser::header::Level::H1 => TextTag::builder()
|
|
||||||
.scale(1.6)
|
|
||||||
.sentence(true)
|
|
||||||
.weight(500)
|
|
||||||
.wrap_mode(WrapMode::Word)
|
|
||||||
.build(),
|
|
||||||
parser::header::Level::H2 => TextTag::builder()
|
|
||||||
.scale(1.4)
|
|
||||||
.sentence(true)
|
|
||||||
.weight(400)
|
|
||||||
.wrap_mode(WrapMode::Word)
|
|
||||||
.build(),
|
|
||||||
parser::header::Level::H3 => TextTag::builder()
|
|
||||||
.scale(1.2)
|
|
||||||
.sentence(true)
|
|
||||||
.weight(400)
|
|
||||||
.wrap_mode(WrapMode::Word)
|
|
||||||
.build(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Register tag in buffer
|
|
||||||
buffer.tag_table().add(&tag);
|
|
||||||
|
|
||||||
// Append value to buffer
|
// Append value to buffer
|
||||||
buffer.insert_with_tags(&mut buffer.end_iter(), header.value.as_str(), &[&tag]);
|
buffer.insert_with_tags(
|
||||||
|
&mut buffer.end_iter(),
|
||||||
|
header.value.as_str(),
|
||||||
|
&[match header.level {
|
||||||
|
parser::header::Level::H1 => tag.h1(),
|
||||||
|
parser::header::Level::H2 => tag.h2(),
|
||||||
|
parser::header::Level::H3 => tag.h3(),
|
||||||
|
}],
|
||||||
|
);
|
||||||
buffer.insert(&mut buffer.end_iter(), "\n");
|
buffer.insert(&mut buffer.end_iter(), "\n");
|
||||||
|
|
||||||
// Update reader title using first gemtext header match
|
// Update reader title using first gemtext header match
|
||||||
@ -176,18 +131,8 @@ impl Reader {
|
|||||||
|
|
||||||
// Is link
|
// Is link
|
||||||
if let Some(link) = Link::from(line, Some(base), Some(&TimeZone::local())) {
|
if let Some(link) = Link::from(line, Some(base), Some(&TimeZone::local())) {
|
||||||
// Init new tag for link
|
|
||||||
let tag = TextTag::builder()
|
|
||||||
.foreground_rgba(&style.accent_color_rgba())
|
|
||||||
.sentence(true)
|
|
||||||
.wrap_mode(WrapMode::Word)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Append tag to buffer
|
|
||||||
buffer.tag_table().add(&tag);
|
|
||||||
|
|
||||||
// Append tag to HashMap storage
|
// Append tag to HashMap storage
|
||||||
links.insert(tag.clone(), link.uri.clone());
|
// links.insert(tag.link(), link.uri.clone()); @TODO
|
||||||
|
|
||||||
// Create vector for alt values
|
// Create vector for alt values
|
||||||
let mut alt = Vec::new();
|
let mut alt = Vec::new();
|
||||||
@ -214,7 +159,7 @@ impl Reader {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Append alt vector values to buffer
|
// Append alt vector values to buffer
|
||||||
buffer.insert_with_tags(&mut buffer.end_iter(), &alt.join(" "), &[&tag]);
|
buffer.insert_with_tags(&mut buffer.end_iter(), &alt.join(" "), &[&tag.link()]);
|
||||||
buffer.insert(&mut buffer.end_iter(), "\n");
|
buffer.insert(&mut buffer.end_iter(), "\n");
|
||||||
|
|
||||||
// Skip other actions for this line
|
// Skip other actions for this line
|
||||||
@ -223,22 +168,11 @@ impl Reader {
|
|||||||
|
|
||||||
// Is list
|
// Is list
|
||||||
if let Some(list) = List::from(line) {
|
if let Some(list) = List::from(line) {
|
||||||
// Build tag from level parsed
|
|
||||||
let tag = TextTag::builder()
|
|
||||||
.left_margin(28)
|
|
||||||
.pixels_above_lines(4)
|
|
||||||
.pixels_below_lines(4)
|
|
||||||
.wrap_mode(WrapMode::Word)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Register tag in buffer
|
|
||||||
buffer.tag_table().add(&tag);
|
|
||||||
|
|
||||||
// Append value to buffer
|
// Append value to buffer
|
||||||
buffer.insert_with_tags(
|
buffer.insert_with_tags(
|
||||||
&mut buffer.end_iter(),
|
&mut buffer.end_iter(),
|
||||||
format!("• {}", list.value).as_str(),
|
format!("• {}", list.value).as_str(),
|
||||||
&[&tag],
|
&[&tag.list()],
|
||||||
);
|
);
|
||||||
buffer.insert(&mut buffer.end_iter(), "\n");
|
buffer.insert(&mut buffer.end_iter(), "\n");
|
||||||
|
|
||||||
@ -248,17 +182,12 @@ impl Reader {
|
|||||||
|
|
||||||
// Is quote
|
// Is quote
|
||||||
if let Some(quote) = Quote::from(line) {
|
if let Some(quote) = Quote::from(line) {
|
||||||
// Build tag from level parsed
|
|
||||||
let tag = TextTag::builder()
|
|
||||||
.style(Style::Italic)
|
|
||||||
.wrap_mode(WrapMode::Word)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Register tag in buffer
|
|
||||||
buffer.tag_table().add(&tag);
|
|
||||||
|
|
||||||
// Append value to buffer
|
// Append value to buffer
|
||||||
buffer.insert_with_tags(&mut buffer.end_iter(), quote.value.as_str(), &[&tag]);
|
buffer.insert_with_tags(
|
||||||
|
&mut buffer.end_iter(),
|
||||||
|
quote.value.as_str(),
|
||||||
|
&[&tag.quote()],
|
||||||
|
);
|
||||||
buffer.insert(&mut buffer.end_iter(), "\n");
|
buffer.insert(&mut buffer.end_iter(), "\n");
|
||||||
|
|
||||||
// Skip other actions for this line
|
// Skip other actions for this line
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
mod code;
|
||||||
|
mod h1;
|
||||||
|
mod h2;
|
||||||
|
mod h3;
|
||||||
|
mod link;
|
||||||
|
mod list;
|
||||||
|
mod quote;
|
||||||
|
mod title;
|
||||||
|
|
||||||
|
use code::Code;
|
||||||
|
use h1::H1;
|
||||||
|
use h2::H2;
|
||||||
|
use h3::H3;
|
||||||
|
use link::Link;
|
||||||
|
use list::List;
|
||||||
|
use quote::Quote;
|
||||||
|
use title::Title;
|
||||||
|
|
||||||
|
use gtk::{TextTag, TextTagTable};
|
||||||
|
|
||||||
|
pub struct Tag {
|
||||||
|
gobject: TextTagTable,
|
||||||
|
// Tags
|
||||||
|
code: Code,
|
||||||
|
h1: H1,
|
||||||
|
h2: H2,
|
||||||
|
h3: H3,
|
||||||
|
link: Link,
|
||||||
|
list: List,
|
||||||
|
quote: Quote,
|
||||||
|
title: Title,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tag {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
// Init components
|
||||||
|
let code = Code::new();
|
||||||
|
let h1 = H1::new();
|
||||||
|
let h2 = H2::new();
|
||||||
|
let h3 = H3::new();
|
||||||
|
let link = Link::new();
|
||||||
|
let list = List::new();
|
||||||
|
let quote = Quote::new();
|
||||||
|
let title = Title::new();
|
||||||
|
|
||||||
|
// Init tag table
|
||||||
|
let gobject = TextTagTable::new();
|
||||||
|
|
||||||
|
gobject.add(code.gobject());
|
||||||
|
gobject.add(h1.gobject());
|
||||||
|
gobject.add(h2.gobject());
|
||||||
|
gobject.add(h3.gobject());
|
||||||
|
gobject.add(title.gobject());
|
||||||
|
gobject.add(link.gobject());
|
||||||
|
gobject.add(list.gobject());
|
||||||
|
gobject.add(quote.gobject());
|
||||||
|
|
||||||
|
Self {
|
||||||
|
gobject,
|
||||||
|
// Tags
|
||||||
|
code,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
link,
|
||||||
|
list,
|
||||||
|
quote,
|
||||||
|
title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTagTable {
|
||||||
|
&self.gobject
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn code(&self) -> &TextTag {
|
||||||
|
&self.code.gobject()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn h1(&self) -> &TextTag {
|
||||||
|
&self.h1.gobject()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn h2(&self) -> &TextTag {
|
||||||
|
&self.h2.gobject()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn h3(&self) -> &TextTag {
|
||||||
|
&self.h3.gobject()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn link(&self) -> &TextTag {
|
||||||
|
&self.link.gobject()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list(&self) -> &TextTag {
|
||||||
|
&self.list.gobject()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn quote(&self) -> &TextTag {
|
||||||
|
&self.quote.gobject()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn title(&self) -> &TextTag {
|
||||||
|
&self.title.gobject()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
use gtk::{TextTag, WrapMode};
|
||||||
|
|
||||||
|
pub struct Code {
|
||||||
|
tag: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Code {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: TextTag::builder()
|
||||||
|
.family("monospace") // @TODO
|
||||||
|
.scale(0.8)
|
||||||
|
.wrap_mode(WrapMode::None)
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTag {
|
||||||
|
&self.tag
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
use gtk::{TextTag, WrapMode};
|
||||||
|
|
||||||
|
pub struct H1 {
|
||||||
|
tag: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl H1 {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: TextTag::builder()
|
||||||
|
.scale(1.6)
|
||||||
|
.sentence(true)
|
||||||
|
.weight(500)
|
||||||
|
.wrap_mode(WrapMode::Word)
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTag {
|
||||||
|
&self.tag
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
use gtk::{TextTag, WrapMode};
|
||||||
|
|
||||||
|
pub struct H2 {
|
||||||
|
tag: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl H2 {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: TextTag::builder()
|
||||||
|
.scale(1.4)
|
||||||
|
.sentence(true)
|
||||||
|
.weight(400)
|
||||||
|
.wrap_mode(WrapMode::Word)
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTag {
|
||||||
|
&self.tag
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
use gtk::{TextTag, WrapMode};
|
||||||
|
|
||||||
|
pub struct H3 {
|
||||||
|
tag: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl H3 {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: TextTag::builder()
|
||||||
|
.scale(1.2)
|
||||||
|
.sentence(true)
|
||||||
|
.weight(400)
|
||||||
|
.wrap_mode(WrapMode::Word)
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTag {
|
||||||
|
&self.tag
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
use adw::StyleManager;
|
||||||
|
use gtk::{TextTag, WrapMode};
|
||||||
|
|
||||||
|
pub struct Link {
|
||||||
|
tag: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Link {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: TextTag::builder()
|
||||||
|
.foreground_rgba(&StyleManager::default().accent_color_rgba()) // @TODO
|
||||||
|
.sentence(true)
|
||||||
|
.wrap_mode(WrapMode::Word)
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTag {
|
||||||
|
&self.tag
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
use gtk::{TextTag, WrapMode};
|
||||||
|
|
||||||
|
pub struct List {
|
||||||
|
tag: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl List {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: TextTag::builder()
|
||||||
|
.left_margin(28)
|
||||||
|
.pixels_above_lines(4)
|
||||||
|
.pixels_below_lines(4)
|
||||||
|
.wrap_mode(WrapMode::Word)
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTag {
|
||||||
|
&self.tag
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
use gtk::{pango::Style, TextTag, WrapMode};
|
||||||
|
|
||||||
|
pub struct Quote {
|
||||||
|
tag: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Quote {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: TextTag::builder()
|
||||||
|
.style(Style::Italic)
|
||||||
|
.wrap_mode(WrapMode::Word)
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTag {
|
||||||
|
&self.tag
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
use gtk::{TextTag, WrapMode};
|
||||||
|
|
||||||
|
pub struct Title {
|
||||||
|
tag: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Title {
|
||||||
|
// Construct
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tag: TextTag::builder()
|
||||||
|
.pixels_above_lines(4)
|
||||||
|
.pixels_below_lines(8)
|
||||||
|
.weight(500)
|
||||||
|
.wrap_mode(WrapMode::None)
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
pub fn gobject(&self) -> &TextTag {
|
||||||
|
&self.tag
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user