use crate::consts::*;
use crate::utils::into_v16;
use crate::markdown::escape::undo_backslash_escape;
pub fn render_code_spans(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_code = false;
let mut last_index = 0;
let mut result = vec![];
for (curr_index, c) in content.iter().enumerate() {
if *c == U16_BACKTICK {
if is_inside_code {
if curr_index > last_index {
result.push(vec![
into_v16("<code class=\"short\">"),
undo_backslash_escape(&content[last_index..curr_index].to_vec()),
into_v16("</code>"),
].concat());
}
else {
result.push(into_v16("``"));
}
}
else {
result.push(content[last_index..curr_index].to_vec());
}
last_index = curr_index + 1;
is_inside_code = !is_inside_code;
}
else if *c == BACKSLASH_ESCAPE_MARKER && curr_index + 1 < content.len() && content[curr_index + 1] == u16::MAX - U16_BACKTICK && is_inside_code {
result.push(vec![
into_v16("<code class=\"short\">"),
undo_backslash_escape(&content[last_index..curr_index].to_vec()),
into_v16("\\</code>"),
].concat());
last_index = curr_index + 2;
is_inside_code = false;
}
}
if is_inside_code {
last_index -= 1;
}
result.push(content[last_index..].to_vec());
result.concat()
}
pub fn render_subscript_and_del(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_subscript = false;
let mut last_index = 0;
let mut result = vec![];
for curr_index in 0..content.len() {
if is_subscript_and_del_delimiter(content, curr_index) {
if is_inside_subscript && content[curr_index - 1] != U16_SPACE && curr_index > last_index {
result.push(into_v16("<sub><del>"));
result.push(content[last_index..curr_index].to_vec());
result.push(into_v16("</del></sub>"));
}
else if !is_inside_subscript && curr_index + 1 < content.len() && content[curr_index + 1] != U16_SPACE && curr_index > last_index {
result.push(content[last_index..curr_index].to_vec());
}
else {
continue;
}
last_index = curr_index + 3;
is_inside_subscript = !is_inside_subscript;
}
if is_inside_subscript && content[curr_index] == U16_SPACE {
last_index -= 3;
is_inside_subscript = false;
}
}
if is_inside_subscript {
last_index -= 3;
}
result.push(content[last_index..].to_vec());
result.concat()
}
fn is_subscript_and_del_delimiter(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_TILDE && index + 2 < content.len() && content[index + 1] == U16_TILDE && content[index + 2] == U16_TILDE
}
pub fn render_bold_and_italic(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_emphasis = false;
let mut last_index = 0;
let mut result = vec![];
for curr_index in 0..content.len() {
if is_bold_and_italic_delimiter(content, curr_index) {
if is_inside_emphasis && content[curr_index - 1] != U16_SPACE && curr_index > last_index {
result.push(into_v16("<em><strong>"));
result.push(content[last_index..curr_index].to_vec());
result.push(into_v16("</strong></em>"));
}
else if !is_inside_emphasis &&curr_index + 1 < content.len() && content[curr_index + 1] != U16_SPACE && curr_index > last_index{
result.push(content[last_index..curr_index].to_vec());
}
else {
continue;
}
last_index = curr_index + 3;
is_inside_emphasis = !is_inside_emphasis;
}
}
if is_inside_emphasis {
last_index -= 3;
}
result.push(content[last_index..].to_vec());
result.concat()
}
fn is_bold_and_italic_delimiter(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_ASTERISK && index + 2 < content.len() && content[index + 1] == U16_ASTERISK && content[index + 2] == U16_ASTERISK
}
pub fn render_italic(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_emphasis = false;
let mut last_index = 0;
let mut result = vec![];
for curr_index in 0..content.len() {
if is_italic_delimiter(content, curr_index) {
if is_inside_emphasis && content[curr_index - 1] != U16_SPACE && curr_index > last_index {
result.push(into_v16("<em>"));
result.push(content[last_index..curr_index].to_vec());
result.push(into_v16("</em>"));
}
else if curr_index + 1 < content.len() && content[curr_index + 1] != U16_SPACE {
result.push(content[last_index..curr_index].to_vec());
}
else {
continue;
}
last_index = curr_index + 1;
is_inside_emphasis = !is_inside_emphasis;
}
}
if is_inside_emphasis {
last_index -= 1;
}
result.push(content[last_index..].to_vec());
result.concat()
}
fn is_italic_delimiter(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_ASTERISK && (
index == 0 || content[index - 1] != U16_ASTERISK
) && (
index == content.len() - 1 || content[index + 1] != U16_ASTERISK
)
}
pub fn render_bold(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_bold = false;
let mut last_index = 0;
let mut result = vec![];
for curr_index in 0..content.len() {
if is_bold_delimiter(content, curr_index) {
if is_inside_bold && content[curr_index - 1] != U16_SPACE && curr_index > last_index {
result.push(into_v16("<strong>"));
result.push(content[last_index..curr_index].to_vec());
result.push(into_v16("</strong>"));
}
else if !is_inside_bold && curr_index + 2 < content.len() && content[curr_index + 2] != U16_SPACE {
result.push(content[last_index..curr_index].to_vec());
}
else {
continue;
}
last_index = curr_index + 2;
is_inside_bold = !is_inside_bold;
}
}
if is_inside_bold {
last_index -= 2;
}
result.push(content[last_index..].to_vec());
result.concat()
}
fn is_bold_delimiter(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_ASTERISK && index + 1 < content.len() && content[index + 1] == U16_ASTERISK
}
pub fn render_del(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_del = false;
let mut last_index = 0;
let mut result = vec![];
for curr_index in 0..content.len() {
if is_del_delimiter(content, curr_index) {
if is_inside_del && content[curr_index - 1] != U16_SPACE && curr_index > last_index {
result.push(into_v16("<del>"));
result.push(content[last_index..curr_index].to_vec());
result.push(into_v16("</del>"));
}
else if !is_inside_del && curr_index + 2 < content.len() && content[curr_index + 2] != U16_SPACE {
result.push(content[last_index..curr_index].to_vec());
}
else {
continue;
}
last_index = curr_index + 2;
is_inside_del = !is_inside_del;
}
}
if is_inside_del {
last_index -= 2;
}
result.push(content[last_index..].to_vec());
result.concat()
}
fn is_del_delimiter(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_TILDE && index + 1 < content.len() && content[index + 1] == U16_TILDE
}
pub fn render_underline(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_underline = false;
let mut last_index = 0;
let mut result = vec![];
for curr_index in 0..content.len() {
if is_inside_underline && is_underline_end(content, curr_index) && curr_index > last_index {
result.push(into_v16("<u>"));
result.push(content[last_index..curr_index].to_vec());
result.push(into_v16("</u>"));
}
else if !is_inside_underline && is_underline_begin(content, curr_index) && curr_index > last_index {
result.push(content[last_index..curr_index].to_vec());
}
else {
continue;
}
is_inside_underline = !is_inside_underline;
last_index = curr_index + 2;
}
if is_inside_underline {
last_index -= 2;
}
result.push(content[last_index..].to_vec());
result.concat()
}
fn is_underline_begin(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_TILDE && index + 2 < content.len() && content[index + 1] == U16_UNDERBAR && content[index + 2] != U16_SPACE
}
fn is_underline_end(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_UNDERBAR && index + 1 < content.len() && content[index + 1] == U16_TILDE && index > 0 && content[index - 1] != U16_SPACE
}
pub fn render_subscript(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_subscript = false;
let mut last_index = 0;
let mut result = vec![];
for curr_index in 0..content.len() {
if is_subscript_delimiter(content, curr_index) {
if is_inside_subscript && content[curr_index - 1] != U16_SPACE && content[curr_index - 1] != U16_UNDERBAR && curr_index > last_index {
result.push(into_v16("<sub>"));
result.push(content[last_index..curr_index].to_vec());
result.push(into_v16("</sub>"));
}
else if curr_index + 1 < content.len() && content[curr_index + 1] != U16_SPACE && content[curr_index + 1] != U16_UNDERBAR {
result.push(content[last_index..curr_index].to_vec());
}
else {
continue;
}
last_index = curr_index + 1;
is_inside_subscript = !is_inside_subscript;
}
if is_inside_subscript && content[curr_index] == U16_SPACE {
last_index -= 1;
is_inside_subscript = false;
}
}
if is_inside_subscript {
last_index -= 1;
}
result.push(content[last_index..].to_vec());
result.concat()
}
fn is_subscript_delimiter(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_TILDE && (
index == 0 || content[index - 1] != U16_TILDE
) && (
index == content.len() - 1 || content[index + 1] != U16_TILDE
)
}
pub fn render_superscript(content: &Vec<u16>) -> Vec<u16> {
let mut is_inside_superscript = false;
let mut last_index = 0;
let mut result = vec![];
for curr_index in 0..content.len() {
if is_superscript_delimiter(content, curr_index) {
if is_inside_superscript && content[curr_index - 1] != U16_SPACE && curr_index > last_index {
result.push(into_v16("<sup>"));
result.push(content[last_index..curr_index].to_vec());
result.push(into_v16("</sup>"));
}
else if curr_index + 1 < content.len() && content[curr_index + 1] != U16_SPACE {
result.push(content[last_index..curr_index].to_vec());
}
else {
continue;
}
last_index = curr_index + 1;
is_inside_superscript = !is_inside_superscript;
}
if is_inside_superscript && content[curr_index] == U16_SPACE {
last_index -= 1;
is_inside_superscript = false;
}
}
if is_inside_superscript {
last_index -= 1;
}
result.push(content[last_index..].to_vec());
result.concat()
}
fn is_superscript_delimiter(content: &Vec<u16>, index: usize) -> bool {
content[index] == U16_CARET && (
index == 0 || content[index - 1] != U16_CARET
) && (
index == content.len() - 1 || content[index + 1] != U16_CARET
)
}