Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
![]() |
dc46f5957e |
5 changed files with 91 additions and 14 deletions
|
@ -13,6 +13,7 @@
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum Item<'a> {
|
pub enum Item<'a> {
|
||||||
/// `\n`
|
/// `\n`
|
||||||
|
// TODO: add Style here so empty heading still uses up the right amount of space.
|
||||||
Newline,
|
Newline,
|
||||||
///
|
///
|
||||||
Text(Style, &'a str),
|
Text(Style, &'a str),
|
||||||
|
@ -48,6 +49,10 @@ pub struct Style {
|
||||||
pub strikethrough: bool,
|
pub strikethrough: bool,
|
||||||
/// /italics/
|
/// /italics/
|
||||||
pub italics: bool,
|
pub italics: bool,
|
||||||
|
/// $small$
|
||||||
|
pub small: bool,
|
||||||
|
/// ^raised^
|
||||||
|
pub raised: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parser for the `EasyMark` markup language.
|
/// Parser for the `EasyMark` markup language.
|
||||||
|
@ -292,6 +297,18 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
self.style.italics = !self.style.italics;
|
self.style.italics = !self.style.italics;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if let Some(rest) = self.s.strip_prefix('$') {
|
||||||
|
self.s = rest;
|
||||||
|
self.start_of_line = false;
|
||||||
|
self.style.small = !self.style.small;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some(rest) = self.s.strip_prefix('^') {
|
||||||
|
self.s = rest;
|
||||||
|
self.start_of_line = false;
|
||||||
|
self.style.raised = !self.style.raised;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// `<url>` or `[link](url)`
|
// `<url>` or `[link](url)`
|
||||||
if let Some(item) = self.url() {
|
if let Some(item) = self.url() {
|
||||||
|
@ -301,7 +318,7 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
// Swallow everything up to the next special character:
|
// Swallow everything up to the next special character:
|
||||||
let end = self
|
let end = self
|
||||||
.s
|
.s
|
||||||
.find(&['*', '`', '~', '_', '/', '\\', '<', '[', '\n'][..])
|
.find(&['*', '`', '~', '_', '/', '$', '^', '\\', '<', '[', '\n'][..])
|
||||||
.map(|special| special.max(1)) // make sure we swallow at least one character
|
.map(|special| special.max(1)) // make sure we swallow at least one character
|
||||||
.unwrap_or_else(|| self.s.len());
|
.unwrap_or_else(|| self.s.len());
|
||||||
|
|
||||||
|
|
|
@ -84,12 +84,19 @@ fn label_from_style(text: &str, style: &easy_mark::Style) -> Label {
|
||||||
underline,
|
underline,
|
||||||
strikethrough,
|
strikethrough,
|
||||||
italics,
|
italics,
|
||||||
|
small,
|
||||||
|
raised,
|
||||||
} = *style;
|
} = *style;
|
||||||
|
|
||||||
|
let small = small || raised; // Raised text is also smaller
|
||||||
|
|
||||||
let mut label = Label::new(text);
|
let mut label = Label::new(text);
|
||||||
if heading {
|
if heading && !small {
|
||||||
label = label.heading().strong();
|
label = label.heading().strong();
|
||||||
}
|
}
|
||||||
|
if small && !heading {
|
||||||
|
label = label.small();
|
||||||
|
}
|
||||||
if code {
|
if code {
|
||||||
label = label.code();
|
label = label.code();
|
||||||
}
|
}
|
||||||
|
@ -107,6 +114,9 @@ fn label_from_style(text: &str, style: &easy_mark::Style) -> Label {
|
||||||
if italics {
|
if italics {
|
||||||
label = label.italics();
|
label = label.italics();
|
||||||
}
|
}
|
||||||
|
if raised {
|
||||||
|
label = label.raised();
|
||||||
|
}
|
||||||
label
|
label
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ pub struct Label {
|
||||||
strikethrough: bool,
|
strikethrough: bool,
|
||||||
underline: bool,
|
underline: bool,
|
||||||
italics: bool,
|
italics: bool,
|
||||||
|
raised: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Label {
|
impl Label {
|
||||||
|
@ -39,6 +40,7 @@ impl Label {
|
||||||
strikethrough: false,
|
strikethrough: false,
|
||||||
underline: false,
|
underline: false,
|
||||||
italics: false,
|
italics: false,
|
||||||
|
raised: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,10 +114,22 @@ impl Label {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Smaller text
|
||||||
pub fn small(self) -> Self {
|
pub fn small(self) -> Self {
|
||||||
self.text_style(TextStyle::Small)
|
self.text_style(TextStyle::Small)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For e.g. exponents
|
||||||
|
pub fn small_raised(self) -> Self {
|
||||||
|
self.text_style(TextStyle::Small).raised()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Align text to top
|
||||||
|
pub fn raised(mut self) -> Self {
|
||||||
|
self.raised = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Fill-color behind the text
|
/// Fill-color behind the text
|
||||||
pub fn background_color(mut self, background_color: impl Into<Color32>) -> Self {
|
pub fn background_color(mut self, background_color: impl Into<Color32>) -> Self {
|
||||||
self.background_color = background_color.into();
|
self.background_color = background_color.into();
|
||||||
|
@ -171,6 +185,7 @@ impl Label {
|
||||||
strikethrough,
|
strikethrough,
|
||||||
underline,
|
underline,
|
||||||
italics,
|
italics,
|
||||||
|
raised: _, // TODO
|
||||||
..
|
..
|
||||||
} = *self;
|
} = *self;
|
||||||
|
|
||||||
|
@ -257,6 +272,7 @@ impl Widget for Label {
|
||||||
|
|
||||||
let text_style = self.text_style_or_default(ui.style());
|
let text_style = self.text_style_or_default(ui.style());
|
||||||
let font = &ui.fonts()[text_style];
|
let font = &ui.fonts()[text_style];
|
||||||
|
let font_height = font.row_height();
|
||||||
let mut galley = font.layout_multiline_with_indentation_and_max_width(
|
let mut galley = font.layout_multiline_with_indentation_and_max_width(
|
||||||
self.text.clone(),
|
self.text.clone(),
|
||||||
first_row_indentation,
|
first_row_indentation,
|
||||||
|
@ -270,18 +286,35 @@ impl Widget for Label {
|
||||||
let id = ui.advance_cursor_after_rect(rect);
|
let id = ui.advance_cursor_after_rect(rect);
|
||||||
let mut response = ui.interact(rect, id, sense);
|
let mut response = ui.interact(rect, id, sense);
|
||||||
|
|
||||||
let mut y_translation = 0.0;
|
// We could be sharing the first row with e.g. a button which is higher than text.
|
||||||
if let Some(row) = galley.rows.get(1) {
|
// So we need to compensate for that:
|
||||||
// We could be sharing the first row with e.g. a button, that is higher than text.
|
if let Some(row) = galley.rows.get_mut(1) {
|
||||||
// So we need to compensate for that:
|
let cursor = ui.cursor();
|
||||||
if pos.y + row.y_min < ui.min_rect().bottom() {
|
|
||||||
y_translation = ui.min_rect().bottom() - row.y_min - pos.y;
|
if pos.y + row.y_min < cursor.bottom() {
|
||||||
|
let y_translation = cursor.bottom() - row.y_min - pos.y;
|
||||||
|
|
||||||
|
if y_translation != 0.0 {
|
||||||
|
for row in galley.rows.iter_mut().skip(1) {
|
||||||
|
row.y_min += y_translation;
|
||||||
|
row.y_max += y_translation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if text_style == TextStyle::Small && !self.raised {
|
||||||
|
for row in galley.rows.iter_mut() {
|
||||||
|
// center:
|
||||||
|
let normal_text_heigth = ui.fonts()[TextStyle::Body].row_height(); // TODO: get from ui
|
||||||
|
let dy = (normal_text_heigth - font_height) / 2.0;
|
||||||
|
|
||||||
|
row.y_min += dy;
|
||||||
|
row.y_max += dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for row in galley.rows.iter_mut().skip(1) {
|
for row in galley.rows.iter_mut().skip(1) {
|
||||||
row.y_min += y_translation;
|
|
||||||
row.y_max += y_translation;
|
|
||||||
let rect = row.rect().translate(vec2(pos.x, pos.y));
|
let rect = row.rect().translate(vec2(pos.x, pos.y));
|
||||||
response |= ui.allocate_rect(rect, sense);
|
response |= ui.allocate_rect(rect, sense);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub(crate) struct State {
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
||||||
struct CursorPair {
|
pub struct CursorPair {
|
||||||
/// When selecting with a mouse, this is where the mouse was released.
|
/// When selecting with a mouse, this is where the mouse was released.
|
||||||
/// When moving with e.g. shift+arrows, this is what moves.
|
/// When moving with e.g. shift+arrows, this is what moves.
|
||||||
/// Note that the two ends can come in any order, and also be equal (no selection).
|
/// Note that the two ends can come in any order, and also be equal (no selection).
|
||||||
|
@ -133,6 +133,14 @@ pub struct TextEdit<'t> {
|
||||||
desired_width: Option<f32>,
|
desired_width: Option<f32>,
|
||||||
desired_height_rows: usize,
|
desired_height_rows: usize,
|
||||||
}
|
}
|
||||||
|
impl<'t> TextEdit<'t> {
|
||||||
|
pub fn cursor(ui: &Ui, id: Id) -> Option<CursorPair> {
|
||||||
|
ui.memory()
|
||||||
|
.text_edit
|
||||||
|
.get(&id)
|
||||||
|
.and_then(|state| state.cursorp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'t> TextEdit<'t> {
|
impl<'t> TextEdit<'t> {
|
||||||
#[deprecated = "Use `TextEdit::singleline` or `TextEdit::multiline` (or the helper `ui.text_edit_singleline`, `ui.text_edit_multiline`) instead"]
|
#[deprecated = "Use `TextEdit::singleline` or `TextEdit::multiline` (or the helper `ui.text_edit_singleline`, `ui.text_edit_multiline`) instead"]
|
||||||
|
|
|
@ -37,8 +37,9 @@ impl EasyMarkEditor {
|
||||||
ScrollArea::auto_sized()
|
ScrollArea::auto_sized()
|
||||||
.id_source("source")
|
.id_source("source")
|
||||||
.show(&mut columns[0], |ui| {
|
.show(&mut columns[0], |ui| {
|
||||||
// ui.text_edit_multiline(&mut self.code);
|
|
||||||
ui.add(TextEdit::multiline(&mut self.code).text_style(TextStyle::Monospace));
|
ui.add(TextEdit::multiline(&mut self.code).text_style(TextStyle::Monospace));
|
||||||
|
// let cursor = TextEdit::cursor(response.id);
|
||||||
|
// TODO: cmd-i, cmd-b, etc for italics, bold, ....
|
||||||
});
|
});
|
||||||
ScrollArea::auto_sized()
|
ScrollArea::auto_sized()
|
||||||
.id_source("rendered")
|
.id_source("rendered")
|
||||||
|
@ -62,7 +63,7 @@ and is also missing some features.
|
||||||
|
|
||||||
# At a glance
|
# At a glance
|
||||||
- inline text:
|
- inline text:
|
||||||
- normal, `code`, *strong*, ~strikethrough~, _underline_, /italics/
|
- normal, `code`, *strong*, ~strikethrough~, _underline_, /italics/, ^raised^, $small$
|
||||||
- `\` escapes the next character
|
- `\` escapes the next character
|
||||||
- [hyperlink](https://github.com/emilk/egui)
|
- [hyperlink](https://github.com/emilk/egui)
|
||||||
- Embedded URL: <https://github.com/emilk/egui>
|
- Embedded URL: <https://github.com/emilk/egui>
|
||||||
|
@ -72,6 +73,8 @@ and is also missing some features.
|
||||||
- `- ` bullet list
|
- `- ` bullet list
|
||||||
- `1. ` numbered list
|
- `1. ` numbered list
|
||||||
- \`\`\` code fence
|
- \`\`\` code fence
|
||||||
|
- You can write exponents like so: x^2^
|
||||||
|
- Remember to read the small print $(terms and conditions apply)$
|
||||||
|
|
||||||
# Design
|
# Design
|
||||||
> /"Why do what everyone else is doing, when everyone else is already doing it?"
|
> /"Why do what everyone else is doing, when everyone else is already doing it?"
|
||||||
|
@ -102,9 +105,11 @@ Escaping the newline effectively ignores it.
|
||||||
|
|
||||||
The style characters are chosen to be similar to what they are representing:
|
The style characters are chosen to be similar to what they are representing:
|
||||||
`_` = _underline_
|
`_` = _underline_
|
||||||
`~` = ~strikethrough~ (`-` is too common in normal text)
|
`~` = ~strikethrough~ (`-` is used for bullet points)
|
||||||
`/` = /italics/
|
`/` = /italics/
|
||||||
`*` = *strong*
|
`*` = *strong*
|
||||||
|
`$` = $small$
|
||||||
|
`^` = ^raised^
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
- Sub-headers (`## h2`, `### h3` etc)
|
- Sub-headers (`## h2`, `### h3` etc)
|
||||||
|
@ -113,5 +118,9 @@ The style characters are chosen to be similar to what they are representing:
|
||||||
- centering of images is very desirable
|
- centering of images is very desirable
|
||||||
- captioning (image with a text underneath it)
|
- captioning (image with a text underneath it)
|
||||||
- `![caption=My image][width=200][center](url)` ?
|
- `![caption=My image][width=200][center](url)` ?
|
||||||
|
- Nicer URL:s
|
||||||
|
- `<url>` and `[url](url)` do the same thing yet look completely different.
|
||||||
|
- let's keep similarity with images
|
||||||
- Tables
|
- Tables
|
||||||
|
- <https://mycorrhiza.lesarbr.es/page/mycomarkup>
|
||||||
"#;
|
"#;
|
||||||
|
|
Loading…
Reference in a new issue