Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor text improvements #1021

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 36 additions & 22 deletions compiler/frontend/src/string_to_rcst/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
rcst::Rcst,
};
use itertools::Itertools;
use std::mem;
use tracing::instrument;

// TODO: It might be a good idea to ignore text interpolations in patterns
Expand Down Expand Up @@ -36,10 +37,10 @@ pub fn text(input: &str, indentation: usize) -> Option<(&str, Rcst)> {
.map(|(i, _)| i)
.nth(1)
{
let (first_whitespace, rest) = opening_whitespace.split_at(second_newline_index);
let rest = opening_whitespace.split_off(second_newline_index);
(
first_whitespace.to_vec(),
convert_whitespace_into_text_newlines(rest.to_vec()),
opening_whitespace,
convert_whitespace_into_text_newlines(rest),
)
} else {
(opening_whitespace, vec![])
Expand All @@ -57,7 +58,7 @@ pub fn text(input: &str, indentation: usize) -> Option<(&str, Rcst)> {
input = input_after_part;
parts.push(part);
} else {
let (input_after_whitespace, whitespace) =
let (input_after_whitespace, mut whitespace) =
whitespaces_and_newlines(input, indentation + 1, false);
input = input_after_whitespace;

Expand All @@ -68,16 +69,16 @@ pub fn text(input: &str, indentation: usize) -> Option<(&str, Rcst)> {
.map(|(i, _)| i)
.next_back()
{
let (whitespace, rest) = whitespace.split_at(last_newline_index);
let mut newlines = convert_whitespace_into_text_newlines(whitespace.to_vec());
let rest = whitespace.split_off(last_newline_index);
let mut newlines = convert_whitespace_into_text_newlines(whitespace);
parts.append(&mut newlines);
rest.to_vec()
rest
} else {
whitespace
};

// Allow closing quotes to have the same indentation level as the opening quotes
let (input_after_whitespace, whitespace) = if newline(input).is_some() {
let (input_after_whitespace, mut whitespace) = if newline(input).is_some() {
whitespaces_and_newlines(input, indentation, false)
} else {
(input, Vec::new())
Expand All @@ -98,10 +99,10 @@ pub fn text(input: &str, indentation: usize) -> Option<(&str, Rcst)> {
.map(|(i, _)| i)
.next_back()
{
let (whitespace, rest) = whitespace.split_at(last_newline_index);
let mut newlines = convert_whitespace_into_text_newlines(whitespace.to_vec());
let rest = whitespace.split_off(last_newline_index);
let mut newlines = convert_whitespace_into_text_newlines(whitespace);
parts.append(&mut newlines);
rest.to_vec()
rest
} else {
let mut newlines =
convert_whitespace_into_text_newlines(whitespace_before_closing_quote);
Expand Down Expand Up @@ -252,25 +253,38 @@ fn text_part(mut input: &str, single_quotes_count: usize) -> Option<(&str, Rcst)
}
}

/// Converts a vec of `CstKind::Newline(…)` and `CstKind::Whitespace(…)` into
/// a vec of `CstKind::TrailingWhitespace { child: CstKind::TextNewline(…), … }`.
#[instrument(level = "trace")]
fn convert_whitespace_into_text_newlines(whitespace: Vec<Rcst>) -> Vec<Rcst> {
fn commit_last_newline(
parts: &mut Vec<Rcst>,
last_newline: Option<Rcst>,
whitespace_after_last_newline: Vec<Rcst>,
) {
if let Some(last_newline) = last_newline {
parts.push(last_newline.wrap_in_whitespace(whitespace_after_last_newline));
}
}

let mut parts: Vec<Rcst> = vec![];
let mut last_newline: Option<Rcst> = None;
let mut whitespace_after_last_newline: Vec<Rcst> = vec![];
let mut parts: Vec<Rcst> = vec![];
for whitespace in whitespace
.iter()
.chain(std::iter::once(&CstKind::Newline("\n".to_string()).into()))
{
if let CstKind::Newline(newline) = whitespace.kind.clone() {
if let Some(last_newline) = last_newline {
parts.push(last_newline.wrap_in_whitespace(whitespace_after_last_newline));
whitespace_after_last_newline = vec![];
}

for whitespace in whitespace {
if let CstKind::Newline(newline) = whitespace.kind {
commit_last_newline(
&mut parts,
last_newline,
mem::take(&mut whitespace_after_last_newline),
);
last_newline = Some(CstKind::TextNewline(newline).into());
} else {
whitespace_after_last_newline.push(whitespace.clone());
whitespace_after_last_newline.push(whitespace);
}
}
commit_last_newline(&mut parts, last_newline, whitespace_after_last_newline);

parts
}

Expand Down
18 changes: 7 additions & 11 deletions packages/AnsiEscapeSequences/example.candy
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
"AnsiEscapeSequences"
[equals, function, int, iterator, text, toDebugText] = use "Core"

## TODO(JonasWanke): Use normal space in text (instead of NBSP) when
## https://github.com/candy-lang/candy/issues/896 is fixed.
nbsp = " "

showGraphicRendition graphicRenditionText content =
# n m SGR Sets colors and style of the characters following this code
needs (text.is graphicRenditionText)
Expand Down Expand Up @@ -35,7 +31,7 @@ showStyles stdout =
iterator.range 9 | iterator.map { index -> index | int.add 1 } | iterator.map { number ->
showGraphicRendition (graphicRenditions.alternativeFont number) "Alternative Font {number}"
}
| iterator.joinToTextWithSeparator nbsp
| iterator.joinToTextWithSeparator " "
stdout (showGraphicRendition graphicRenditions.fraktur "Fraktur")
stdout (showGraphicRendition graphicRenditions.doublyUnderlined "Doubly Underlined")
stdout (showGraphicRendition graphicRenditions.normalIntensity "Normal Intensity")
Expand Down Expand Up @@ -78,9 +74,9 @@ showColors3Or4Bit stdout =
line graphicRenditionFunction content =
needs (function.is1 graphicRenditionFunction)
needs (text.is content)
coloredLine 0 8 graphicRenditionFunction { color -> content } nbsp
columnHeaders = iterator.range 8 | iterator.map { color -> "{nbsp}{color} " }
| iterator.joinToTextWithSeparator nbsp
coloredLine 0 8 graphicRenditionFunction { color -> content } " "
columnHeaders =
iterator.range 8 | iterator.map { color -> " {color} " } | iterator.joinToTextWithSeparator " "

stdout "# Colors: 3 and 4 Bit"
stdout ""
Expand All @@ -89,8 +85,8 @@ showColors3Or4Bit stdout =
stdout "Bright: {line graphicRenditions.setBrightForegroundColor3Or4Bit "▓▓▓"}"
stdout ""
stdout "Background {columnHeaders}"
stdout "Normal: {line graphicRenditions.setBackgroundColor3Or4Bit "{nbsp} "}"
stdout "Bright: {line graphicRenditions.setBrightBackgroundColor3Or4Bit "{nbsp} "}"
stdout "Normal: {line graphicRenditions.setBackgroundColor3Or4Bit " "}"
stdout "Bright: {line graphicRenditions.setBrightBackgroundColor3Or4Bit " "}"

showColors8Bit stdout =
needs (function.is1 stdout)
Expand Down Expand Up @@ -126,7 +122,7 @@ showColors8Bit stdout =
stdout ""
block graphicRenditions.setForegroundColor8Or24Bit "▓"
stdout ""
block graphicRenditions.setBackgroundColor8Or24Bit nbsp
block graphicRenditions.setBackgroundColor8Or24Bit " "

main := { environment ->
showStyles environment.stdout
Expand Down
2 changes: 1 addition & 1 deletion packages/Csv/encode.candy
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ encode lines :=
| iterator.joinToText

testEncodeLine =
# TODO(JonaWanke): Add tests cases for leading/trailing whitespace when our parser is fixed,
# TODO(JonaWanke): Add test cases for leading/trailing whitespace when our parser is fixed,
# https://github.com/candy-lang/candy/issues/896
checkEquals (encodeLine (,)) ""
checkEquals (encodeLine ("aaa",)) "aaa"
Expand Down
Loading