Skip to content

Commit 13b9251

Browse files
CopilotMaestroError
andcommitted
Add newline character handling for markdown table cells
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
1 parent aa430db commit 13b9251

File tree

2 files changed

+168
-6
lines changed

2 files changed

+168
-6
lines changed

src/Services/PropertiesTable.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ public function convertPropertiesToMarkdownTable(array $properties): string
2929
continue;
3030
}
3131

32-
// Escape pipe characters in property name and value
33-
$escapedName = $this->escapePipeCharacters($name);
34-
$escapedValue = $this->escapePipeCharacters($value);
32+
// Escape special characters in property name and value
33+
$escapedName = $this->escapeTableCellCharacters($name);
34+
$escapedValue = $this->escapeTableCellCharacters($value);
3535

3636
$markdown .= "| {$escapedName} | {$escapedValue} |\n";
3737
}
@@ -295,13 +295,19 @@ private function formatUser(?array $user): string
295295
}
296296

297297
/**
298-
* Escape pipe characters in markdown table cells
298+
* Escape special characters in markdown table cells
299299
*
300300
* @param string $text Text to escape
301301
* @return string Escaped text
302302
*/
303-
private function escapePipeCharacters(string $text): string
303+
private function escapeTableCellCharacters(string $text): string
304304
{
305-
return str_replace('|', '\|', $text);
305+
// Escape pipe characters to prevent table structure corruption
306+
$text = str_replace('|', '\|', $text);
307+
308+
// Replace newline characters with spaces to maintain table structure
309+
$text = str_replace(["\r\n", "\r", "\n"], ' ', $text);
310+
311+
return $text;
306312
}
307313
}

tests/Services/PropertiesTableTest.php

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,3 +653,159 @@
653653

654654
expect($result)->toContain('| Calculated | Result \| Text |');
655655
});
656+
657+
test('replaces newline characters with spaces in property values', function () {
658+
$properties = [
659+
'Description' => [
660+
'id' => 'rich',
661+
'type' => 'rich_text',
662+
'rich_text' => [
663+
['plain_text' => "Line 1\nLine 2"],
664+
],
665+
],
666+
];
667+
668+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
669+
670+
expect($result)->toContain('| Description | Line 1 Line 2 |');
671+
});
672+
673+
test('replaces carriage return with spaces in property values', function () {
674+
$properties = [
675+
'Description' => [
676+
'id' => 'rich',
677+
'type' => 'rich_text',
678+
'rich_text' => [
679+
['plain_text' => "Line 1\rLine 2"],
680+
],
681+
],
682+
];
683+
684+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
685+
686+
expect($result)->toContain('| Description | Line 1 Line 2 |');
687+
});
688+
689+
test('replaces CRLF with spaces in property values', function () {
690+
$properties = [
691+
'Description' => [
692+
'id' => 'rich',
693+
'type' => 'rich_text',
694+
'rich_text' => [
695+
['plain_text' => "Line 1\r\nLine 2"],
696+
],
697+
],
698+
];
699+
700+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
701+
702+
expect($result)->toContain('| Description | Line 1 Line 2 |');
703+
});
704+
705+
test('replaces multiple newlines with spaces in property values', function () {
706+
$properties = [
707+
'Description' => [
708+
'id' => 'rich',
709+
'type' => 'rich_text',
710+
'rich_text' => [
711+
['plain_text' => "Line 1\n\nLine 2\n\nLine 3"],
712+
],
713+
],
714+
];
715+
716+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
717+
718+
expect($result)->toContain('| Description | Line 1 Line 2 Line 3 |');
719+
});
720+
721+
test('replaces newlines in property names', function () {
722+
$properties = [
723+
"Multi\nLine\nName" => [
724+
'id' => 'title',
725+
'type' => 'title',
726+
'title' => [
727+
['plain_text' => 'Test Value'],
728+
],
729+
],
730+
];
731+
732+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
733+
734+
expect($result)->toContain('| Multi Line Name | Test Value |');
735+
});
736+
737+
test('handles both newlines and pipe characters together', function () {
738+
$properties = [
739+
"Name | Title\nWith Newline" => [
740+
'id' => 'rich',
741+
'type' => 'rich_text',
742+
'rich_text' => [
743+
['plain_text' => "Value | with\npipe and\nnewlines"],
744+
],
745+
],
746+
];
747+
748+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
749+
750+
expect($result)->toContain('| Name \| Title With Newline | Value \| with pipe and newlines |');
751+
});
752+
753+
test('replaces newlines in select property values', function () {
754+
$properties = [
755+
'Type' => [
756+
'id' => 'select',
757+
'type' => 'select',
758+
'select' => [
759+
'id' => 'LOQu',
760+
'name' => "Option\nWith\nNewlines",
761+
'color' => 'pink',
762+
],
763+
],
764+
];
765+
766+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
767+
768+
expect($result)->toContain('| Type | Option With Newlines |');
769+
});
770+
771+
test('replaces newlines in multi_select property values', function () {
772+
$properties = [
773+
'Tags' => [
774+
'id' => 'multi_select',
775+
'type' => 'multi_select',
776+
'multi_select' => [
777+
[
778+
'id' => 'tag1',
779+
'name' => "Tag\n1",
780+
'color' => 'blue',
781+
],
782+
[
783+
'id' => 'tag2',
784+
'name' => "Tag\n2",
785+
'color' => 'green',
786+
],
787+
],
788+
],
789+
];
790+
791+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
792+
793+
expect($result)->toContain('| Tags | Tag 1, Tag 2 |');
794+
});
795+
796+
test('replaces newlines in people names', function () {
797+
$properties = [
798+
'Person' => [
799+
'id' => 'people',
800+
'type' => 'people',
801+
'people' => [
802+
['name' => "John\nDoe"],
803+
['name' => "Jane\nSmith"],
804+
],
805+
],
806+
];
807+
808+
$result = $this->propertiesTable->convertPropertiesToMarkdownTable($properties);
809+
810+
expect($result)->toContain('| Person | John Doe, Jane Smith |');
811+
});

0 commit comments

Comments
 (0)