Skip to content

Commit 16a5f68

Browse files
BernieWhitevors
authored andcommitted
Fix to preserve line break after headers issue #319 (#321)
* Updates to preserve blank line after header #319 * Updates to preserve blank line after header for examples and parameters * Updates to preserve parameter, input, output and to remove trailing line breaks related links * Avoid adding 2 extra lines after parameter body
1 parent 4ca79b2 commit 16a5f68

27 files changed

+713
-172
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
## Not released
55

66
* Clean up trailing whitespace during markdown generation [#225](https://github.com/PowerShell/platyPS/issues/225)
7+
* Preserve line breaks after headers when Update-MarkdownHelp is used [#319](https://github.com/PowerShell/platyPS/issues/319)
78

89
## 0.8.3
910

src/Markdown.MAML/Markdown.MAML.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
<Compile Include="Model\Markdown\MarkdownNode.cs" />
6262
<Compile Include="Model\Markdown\MarkdownNodeType.cs" />
6363
<Compile Include="Model\Markdown\ParagraphNode.cs" />
64+
<Compile Include="Model\Markdown\SectionBody.cs" />
65+
<Compile Include="Model\Markdown\SectionFormatOption.cs" />
6466
<Compile Include="Model\Markdown\SourceExtent.cs" />
6567
<Compile Include="Model\Markdown\TextNode.cs" />
6668
<Compile Include="Model\Markdown\HyperlinkSpan.cs" />

src/Markdown.MAML/Model/MAML/MamlCommand.cs

+6-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ namespace Markdown.MAML.Model.MAML
66
public class MamlCommand
77
{
88
public SourceExtent Extent { get; set; }
9+
910
public string Name { get; set; }
10-
public string Synopsis { get; set; }
11-
public string Description { get; set; }
11+
12+
public SectionBody Synopsis { get; set; }
13+
14+
public SectionBody Description { get; set; }
1215

1316
public List<MamlInputOutput> Inputs
1417
{
@@ -25,7 +28,7 @@ public List<MamlParameter> Parameters
2528
get { return _parameters; }
2629
}
2730

28-
public string Notes { get; set; }
31+
public SectionBody Notes { get; set; }
2932

3033
public bool IsWorkflow { get; set; }
3134

src/Markdown.MAML/Model/MAML/MamlExample.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using Markdown.MAML.Model.Markdown;
2+
using System;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Text;
@@ -12,5 +13,10 @@ public class MamlExample
1213
public string Code { get; set; }
1314
public string Remarks { get; set; }
1415
public string Introduction { get; set; }
16+
17+
/// <summary>
18+
/// Additional options that determine how the section will be formated when rendering markdown.
19+
/// </summary>
20+
public SectionFormatOption FormatOption { get; set; }
1521
}
1622
}

src/Markdown.MAML/Model/MAML/MamlInputOutput.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using Markdown.MAML.Model.Markdown;
2+
using System;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Text;
@@ -14,6 +15,11 @@ public class MamlInputOutput : IEquatable<MamlInputOutput>
1415
public string TypeName { get; set; }
1516
public string Description { get; set; }
1617

18+
/// <summary>
19+
/// Additional options that determine how the section will be formated when rendering markdown.
20+
/// </summary>
21+
public SectionFormatOption FormatOption { get; set; }
22+
1723
bool IEquatable<MamlInputOutput>.Equals(MamlInputOutput other)
1824
{
1925
if (!StringComparer.OrdinalIgnoreCase.Equals(other.TypeName, this.TypeName))

src/Markdown.MAML/Model/MAML/MamlParameter.cs

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ public class MamlParameter : ICloneable
99
{
1010
public SourceExtent Extent { get; set; }
1111

12+
/// <summary>
13+
/// Additional options that determine how the section will be formated when rendering markdown.
14+
/// </summary>
15+
public SectionFormatOption FormatOption { get; set; }
16+
1217
public string Type { get; set; }
1318

1419
public string FullType { get; set; }

src/Markdown.MAML/Model/Markdown/HeadingNode.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ public override MarkdownNodeType NodeType
99

1010
public int HeadingLevel { get; private set; }
1111

12-
public HeadingNode(string headingText, int headingLevel, SourceExtent sourceExtent)
12+
/// <summary>
13+
/// Additional options that determine how the section will be formated when rendering markdown. This options will be passed on to MAML models when they are generated.
14+
/// </summary>
15+
public SectionFormatOption FormatOption { get; private set; }
16+
17+
public HeadingNode(string headingText, int headingLevel, SourceExtent sourceExtent, SectionFormatOption formatOption)
1318
: base(headingText, sourceExtent)
1419
{
1520
this.HeadingLevel = headingLevel;
21+
this.FormatOption = formatOption;
1622
}
1723
}
1824
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Markdown.MAML.Model.Markdown
8+
{
9+
/// <summary>
10+
/// A section of text with formatting options.
11+
/// </summary>
12+
public sealed class SectionBody
13+
{
14+
public SectionBody(string text, SectionFormatOption formatOption)
15+
{
16+
Text = text;
17+
FormatOption = formatOption;
18+
}
19+
20+
public SectionBody(string text)
21+
: this(text, SectionFormatOption.None)
22+
{ }
23+
24+
/// <summary>
25+
/// The text of the section body.
26+
/// </summary>
27+
public string Text { get; private set; }
28+
29+
/// <summary>
30+
/// Additional options that determine how the section will be formated when rendering markdown.
31+
/// </summary>
32+
public SectionFormatOption FormatOption { get; private set; }
33+
34+
public override string ToString()
35+
{
36+
return Text;
37+
}
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Markdown.MAML.Model.Markdown
8+
{
9+
/// <summary>
10+
/// Define options that determine how sections will be formated when rendering markdown.
11+
/// </summary>
12+
[Flags()]
13+
public enum SectionFormatOption : byte
14+
{
15+
None = 0,
16+
17+
/// <summary>
18+
/// A line break should be added after the section header.
19+
/// </summary>
20+
LineBreakAfterHeader = 1
21+
}
22+
}

src/Markdown.MAML/Parser/MarkdownParser.cs

+12-3
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,10 @@ private void CreateHashHeader(Match regexMatch, SourceExtent sourceExtent)
307307
new HeadingNode(
308308
regexMatch.Groups[2].Value,
309309
regexMatch.Groups[1].Value.Length,
310-
sourceExtent));
310+
sourceExtent,
311+
312+
// Detect if a line break after the header exists. Mutiple line breaks will be reduced to one.
313+
(regexMatch.Groups[3].Captures.Count > 1) ? SectionFormatOption.LineBreakAfterHeader : SectionFormatOption.None));
311314
}
312315

313316
private void CreateHashHeader2(Match regexMatch, SourceExtent sourceExtent)
@@ -318,7 +321,10 @@ private void CreateHashHeader2(Match regexMatch, SourceExtent sourceExtent)
318321
new HeadingNode(
319322
regexMatch.Groups[3].Value,
320323
regexMatch.Groups[2].Value.Length,
321-
sourceExtent));
324+
sourceExtent,
325+
326+
// Detect if a line break after the header exists. Mutiple line breaks will be reduced to one.
327+
(regexMatch.Groups[4].Captures.Count > 1) ? SectionFormatOption.LineBreakAfterHeader : SectionFormatOption.None));
322328
}
323329

324330
private void CreateUnderlineHeader(Match regexMatch, SourceExtent sourceExtent)
@@ -333,7 +339,10 @@ private void CreateUnderlineHeader(Match regexMatch, SourceExtent sourceExtent)
333339
new HeadingNode(
334340
regexMatch.Groups[1].Value,
335341
headerLevel,
336-
sourceExtent));
342+
sourceExtent,
343+
344+
// Detect if a line break after the header exists. Mutiple line breaks will be reduced to one.
345+
(regexMatch.Groups[3].Captures.Count > 1) ? SectionFormatOption.LineBreakAfterHeader : SectionFormatOption.None));
337346
}
338347

339348
private void CreateTickCodeBlock(Match regexMatch, SourceExtent sourceExtent)

src/Markdown.MAML/Renderer/MamlRenderer.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ private static XElement CreateCommandElement(MamlCommand command)
6464
new XElement(commandNS + "name", command.Name),
6565
new XElement(commandNS + "verb", verb),
6666
new XElement(commandNS + "noun", noun),
67-
new XElement(mamlNS + "description", GenerateParagraphs(command.Synopsis))),
68-
new XElement(mamlNS + "description", GenerateParagraphs(command.Description)),
67+
new XElement(mamlNS + "description", GenerateParagraphs(command.Synopsis?.Text))),
68+
new XElement(mamlNS + "description", GenerateParagraphs(command.Description?.Text)),
6969
new XElement(commandNS + "syntax", command.Syntax.Select(syn => CreateSyntaxItem(syn, command))),
7070
new XElement(commandNS + "parameters", command.Parameters.Select(param => CreateParameter(param))),
7171
new XElement(commandNS + "inputTypes", command.Inputs.Select(input => CreateInput(input))),
7272
new XElement(commandNS + "returnValues", command.Outputs.Select(output => CreateOutput(output))),
7373
new XElement(mamlNS + "alertSet",
74-
new XElement(mamlNS + "alert", GenerateParagraphs(command.Notes))),
74+
new XElement(mamlNS + "alert", GenerateParagraphs(command.Notes?.Text))),
7575
new XElement(commandNS + "examples", command.Examples.Select(example => CreateExample(example))),
7676
new XElement(commandNS + "relatedLinks", command.Links.Select(link => CreateLink(link))));
7777
}

src/Markdown.MAML/Renderer/Markdownv2Renderer.cs

+32-12
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ private void AddCommand(MamlCommand command)
114114

115115
private void AddLinks(MamlCommand command)
116116
{
117-
AddHeader(ModelTransformerBase.COMMAND_ENTRIES_HEADING_LEVEL, MarkdownStrings.RELATED_LINKS);
117+
var extraNewLine = command.Links != null && command.Links.Count > 0;
118+
119+
AddHeader(ModelTransformerBase.COMMAND_ENTRIES_HEADING_LEVEL, MarkdownStrings.RELATED_LINKS, extraNewLine);
118120
foreach (var link in command.Links)
119121
{
120122
if (link.IsSimplifiedTextLink)
@@ -143,7 +145,7 @@ private void AddInputOutput(MamlInputOutput io)
143145
return;
144146
}
145147

146-
var extraNewLine = string.IsNullOrEmpty(io.Description);
148+
var extraNewLine = string.IsNullOrEmpty(io.Description) || ShouldBreak(io.FormatOption);
147149
AddHeader(ModelTransformerBase.INPUT_OUTPUT_TYPENAME_HEADING_LEVEL, io.TypeName, extraNewLine);
148150
AddParagraphs(io.Description);
149151
}
@@ -265,9 +267,18 @@ private string JoinWithComma(IEnumerable<string> args)
265267
return string.Join(", ", args);
266268
}
267269

270+
private bool ShouldBreak(SectionFormatOption formatOption)
271+
{
272+
// If the line break flag is set return true.
273+
return formatOption.HasFlag(SectionFormatOption.LineBreakAfterHeader);
274+
}
275+
268276
private void AddParameter(MamlParameter parameter, MamlCommand command)
269277
{
270-
AddHeader(ModelTransformerBase.PARAMETERSET_NAME_HEADING_LEVEL, '-' + parameter.Name, extraNewLine: false);
278+
var extraNewLine = ShouldBreak(parameter.FormatOption);
279+
280+
AddHeader(ModelTransformerBase.PARAMETERSET_NAME_HEADING_LEVEL, '-' + parameter.Name, extraNewLine: extraNewLine);
281+
271282
// for some reason, in the update mode parameters produces extra newline.
272283
AddParagraphs(parameter.Description, this._mode == ParserMode.FormattingPreserve);
273284

@@ -332,7 +343,10 @@ private void AddExamples(MamlCommand command)
332343
AddHeader(ModelTransformerBase.COMMAND_ENTRIES_HEADING_LEVEL, MarkdownStrings.EXAMPLES);
333344
foreach (var example in command.Examples)
334345
{
335-
AddHeader(ModelTransformerBase.EXAMPLE_HEADING_LEVEL, example.Title, extraNewLine: false);
346+
var extraNewLine = ShouldBreak(example.FormatOption);
347+
348+
AddHeader(ModelTransformerBase.EXAMPLE_HEADING_LEVEL, example.Title, extraNewLine: extraNewLine);
349+
336350
if (!string.IsNullOrEmpty(example.Introduction))
337351
{
338352
AddParagraphs(example.Introduction);
@@ -432,17 +446,17 @@ private void AddSyntax(MamlCommand command)
432446
}
433447
}
434448

435-
private void AddEntryHeaderWithText(string header, string text)
449+
private void AddEntryHeaderWithText(string header, SectionBody body)
436450
{
437-
AddHeader(ModelTransformerBase.COMMAND_ENTRIES_HEADING_LEVEL, header, extraNewLine: false);
451+
var extraNewLine = body == null || string.IsNullOrEmpty(body.Text) || ShouldBreak(body.FormatOption);
452+
453+
// Add header
454+
AddHeader(ModelTransformerBase.COMMAND_ENTRIES_HEADING_LEVEL, header, extraNewLine: extraNewLine);
455+
438456
// to correctly handle empty text case, we are adding new-line here
439-
if (string.IsNullOrEmpty(text))
440-
{
441-
_stringBuilder.Append(Environment.NewLine);
442-
}
443-
else
457+
if (body != null && !string.IsNullOrEmpty(body.Text))
444458
{
445-
AddParagraphs(text);
459+
AddParagraphs(body.Text);
446460
}
447461
}
448462

@@ -525,6 +539,12 @@ private void AddParagraphs(string body, bool noNewLines = false)
525539
body = GetAutoWrappingForMarkdown(paragraphs.Select(para => GetEscapedMarkdownText(para.Trim())).ToArray());
526540
}
527541

542+
// The the body already ended in a line break don't add extra lines on to the end
543+
if (body.EndsWith("\r\n\r\n"))
544+
{
545+
noNewLines = true;
546+
}
547+
528548
_stringBuilder.AppendFormat("{0}{1}{1}", body, noNewLines ? null : Environment.NewLine);
529549
}
530550

src/Markdown.MAML/Renderer/YamlRenderer.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ public static string MamlModelToString(MamlCommand mamlCommand)
2222
var model = new YamlCommand
2323
{
2424
Name = mamlCommand.Name,
25-
Notes = mamlCommand.Notes,
26-
Remarks = mamlCommand.Description,
27-
Summary = mamlCommand.Synopsis,
25+
Notes = mamlCommand.Notes.Text,
26+
Remarks = mamlCommand.Description.Text,
27+
Summary = mamlCommand.Synopsis.Text,
2828
Examples = mamlCommand.Examples.Select(CreateExample).ToList(),
2929
Inputs = mamlCommand.Inputs.Select(CreateInputOutput).ToList(),
3030
Links = mamlCommand.Links.Select(CreateLink).ToList(),

0 commit comments

Comments
 (0)