Skip to content

Commit

Permalink
move to begin-snippet: convention
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonCropp committed May 26, 2019
1 parent cc47312 commit 20bedc2
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 25 deletions.
22 changes: 13 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,24 @@ There is also a [.net API](/docs/api.md) and an [MsBuild Task](/docs/msbuild.md)

## Installation

Install the dotnet tool https://nuget.org/packages/MarkdownSnippets.Tool/ [![NuGet Status](http://img.shields.io/nuget/v/MarkdownSnippets.Tool.svg?style=flat)](https://www.nuget.org/packages/MarkdownSnippets.Tool/)
Ensure [dotnet CLI is installed](https://docs.microsoft.com/en-us/dotnet/core/tools/).

**There is known a issue with dotnet tools on macOS and Linux that results in [tools not being discovered in the current path](https://github.com/dotnet/cli/issues/9321). The workaround is to add `~/.dotnet/tools` to the PATH.**

Install MarkdownSnippets.Tool https://nuget.org/packages/MarkdownSnippets.Tool/ [![NuGet Status](http://img.shields.io/nuget/v/MarkdownSnippets.Tool.svg?style=flat)](https://www.nuget.org/packages/MarkdownSnippets.Tool/)

```ps
dotnet tool install -g MarkdownSnippets.Tool
```


## Usage

```ps
mdsnippets C:\Code\TheTargetDirectory
mdsnippets C:\Code\TargetDirectory
```

If no directory is passed the current directory will be used, but only if it exists with a git repository directory tree. If not an error is returned.

**There is known a issue on macOS and Linux that results in [dotnet tools not being discovered in the current path](https://github.com/dotnet/cli/issues/9321).**


### Behavior

Expand All @@ -47,15 +48,18 @@ When using `mdsource` convention, all references to other files, such as links a

## Defining Snippets

Any code wrapped in a convention based comment will be picked up. The comment needs to start with `startcode` which is followed by the key. The snippet is then terminated by `endcode`.
Any code wrapped in a convention based comment will be picked up. The comment needs to start with `begin-snippet:` which is followed by the key. The snippet is then terminated by `end-snippet`.

```
// startcode MySnippetName
// begin-snippet: MySnippetName
My Snippet Code
// endcode
// end-snippet
```

Named C# regions will also be picked up, with the name of the region is used as the key.
There is a legacy convention for defining snippets. Where a snippet starts with `startcode` and ends with `endcode`. This convention will be removed in a future release.


Named [C# regions](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-region) will also be picked up, with the name of the region is used as the key.


## Using Snippets
Expand Down
22 changes: 13 additions & 9 deletions readme.source.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@ There is also a [.net API](/docs/api.md) and an [MsBuild Task](/docs/msbuild.md)

## Installation

Install the dotnet tool https://nuget.org/packages/MarkdownSnippets.Tool/ [![NuGet Status](http://img.shields.io/nuget/v/MarkdownSnippets.Tool.svg?style=flat)](https://www.nuget.org/packages/MarkdownSnippets.Tool/)
Ensure [dotnet CLI is installed](https://docs.microsoft.com/en-us/dotnet/core/tools/).

**There is known a issue with dotnet tools on macOS and Linux that results in [tools not being discovered in the current path](https://github.com/dotnet/cli/issues/9321). The workaround is to add `~/.dotnet/tools` to the PATH.**

Install MarkdownSnippets.Tool https://nuget.org/packages/MarkdownSnippets.Tool/ [![NuGet Status](http://img.shields.io/nuget/v/MarkdownSnippets.Tool.svg?style=flat)](https://www.nuget.org/packages/MarkdownSnippets.Tool/)

```ps
dotnet tool install -g MarkdownSnippets.Tool
```


## Usage

```ps
mdsnippets C:\Code\TheTargetDirectory
mdsnippets C:\Code\TargetDirectory
```

If no directory is passed the current directory will be used, but only if it exists with a git repository directory tree. If not an error is returned.

**There is known a issue on macOS and Linux that results in [dotnet tools not being discovered in the current path](https://github.com/dotnet/cli/issues/9321).**


### Behavior

Expand All @@ -41,15 +42,18 @@ When using `mdsource` convention, all references to other files, such as links a

## Defining Snippets

Any code wrapped in a convention based comment will be picked up. The comment needs to start with `startcode` which is followed by the key. The snippet is then terminated by `endcode`.
Any code wrapped in a convention based comment will be picked up. The comment needs to start with `begin-snippet:` which is followed by the key. The snippet is then terminated by `end-snippet`.

```
// startcode MySnippetName
// begin-snippet: MySnippetName
My Snippet Code
// endcode
// end-snippet
```

Named C# regions will also be picked up, with the name of the region is used as the key.
There is a legacy convention for defining snippets. Where a snippet starts with `startcode` and ends with `endcode`. This convention will be removed in a future release.


Named [C# regions](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-region) will also be picked up, with the name of the region is used as the key.


## Using Snippets
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<LangVersion>latest</LangVersion>
<NoWarn>CS1591</NoWarn>
<NoPackageAnalysis>true</NoPackageAnalysis>
<Version>10.2.1</Version>
<Version>10.3.0</Version>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>Copyright $([System.DateTime]::UtcNow.ToString(yyyy)). All rights reserved</Copyright>
<PackageIconUrl>https://raw.githubusercontent.com/SimonCropp/MarkdownSnippets/master/src/icon.png</PackageIconUrl>
Expand Down
33 changes: 28 additions & 5 deletions src/MarkdownSnippets/Reading/StartEndTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@

static class StartEndTester
{
static Func<string, bool> isEndCode = IsEndCode;
static Func<string, bool> isEndRegion = IsEndRegion;

internal static bool IsStart(string trimmedLine, string path, out string currentKey, out Func<string, bool> endFunc)
{
if (IsBeginSnippet(trimmedLine, path, out currentKey))
{
endFunc = IsEndSnippet;
return true;
}

if (IsStartCode(trimmedLine, path, out currentKey))
{
endFunc = isEndCode;
endFunc = IsEndCode;
return true;
}

if (IsStartRegion(trimmedLine, path, out currentKey))
{
endFunc = isEndRegion;
endFunc = IsEndRegion;
return true;
}

Expand All @@ -34,6 +37,11 @@ static bool IsEndCode(string line)
return line.IndexOf("endcode", StringComparison.Ordinal) >= 0;
}

static bool IsEndSnippet(string line)
{
return line.IndexOf("end-snippet", StringComparison.Ordinal) >= 0;
}

internal static bool IsStartRegion(string line, string path, out string key)
{
if (!line.StartsWith("#region ", StringComparison.Ordinal))
Expand All @@ -45,6 +53,21 @@ internal static bool IsStartRegion(string line, string path, out string key)
return TryExtractParts(substring, line, false, path, out key);
}

internal static bool IsBeginSnippet(string line, string path, out string key)
{
var startCodeIndex = line.IndexOf("begin-snippet: ", StringComparison.Ordinal);
if (startCodeIndex == -1)
{
key = null;
return false;
}
var startIndex = startCodeIndex + 15;
var substring = line
.TrimBackCommentChars(startIndex);
return TryExtractParts(substring, line, true, path, out key);
}


internal static bool IsStartCode(string line, string path, out string key)
{
var startCodeIndex = line.IndexOf("startcode ", StringComparison.Ordinal);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Key should not start or end with symbols.
Key: key_
Path: file
Line: <!-- begin-snippet: key_ -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Key should not start or end with symbols.
Key: _key
Path: file
Line: <!-- begin-snippet: _key-->
107 changes: 107 additions & 0 deletions src/Tests/StartEndTesterIsBeginSnippetTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using ApprovalTests;
using MarkdownSnippets;
using Xunit;
using Xunit.Abstractions;

public class StartEndTesterIsBeginSnippetTests :
TestBase
{
[Fact]
public void CanExtractFromXml()
{
var isStartCode = StartEndTester.IsBeginSnippet("<!-- begin-snippet: CodeKey -->", "file", out var key);
Assert.True(isStartCode);
Assert.Equal("CodeKey", key);
}

[Fact]
public void ShouldThrowForNoKey()
{
var exception = Assert.Throws<SnippetReadingException>(() => StartEndTester.IsBeginSnippet("<!-- begin-snippet: -->", "file", out _));
Assert.Equal("No Key could be derived. Line: '<!-- begin-snippet: -->'.", exception.Message);
}

[Fact]
public void ShouldNotThrowForNoKeyWithNoSpace()
{
StartEndTester.IsBeginSnippet("<!--begin-snippet:-->", "file", out _);
}

[Fact]
public void CanExtractFromXmlWithMissingSpaces()
{
var isStartCode = StartEndTester.IsBeginSnippet("<!--begin-snippet: CodeKey-->", "file", out var key);
Assert.True(isStartCode);
Assert.Equal("CodeKey", key);
}

[Fact]
public void CanExtractFromXmlWithExtraSpaces()
{
var isStartCode = StartEndTester.IsBeginSnippet("<!-- begin-snippet: CodeKey -->", "file", out var key);
Assert.True(isStartCode);
Assert.Equal("CodeKey", key);
}

[Fact]
public void CanExtractWithNoTrailingCharacters()
{
var isStartCode = StartEndTester.IsBeginSnippet("<!-- begin-snippet: CodeKey", "file", out var key);
Assert.True(isStartCode);
Assert.Equal("CodeKey", key);
}

[Fact]
public void CanExtractWithUnderScores()
{
var isStartCode = StartEndTester.IsBeginSnippet("<!-- begin-snippet: Code_Key -->", "file", out var key);
Assert.True(isStartCode);
Assert.Equal("Code_Key", key);
}

[Fact]
public void CanExtractWithDashes()
{
var isStartCode = StartEndTester.IsBeginSnippet("<!-- begin-snippet: Code-Key -->", "file", out var key);
Assert.True(isStartCode);
Assert.Equal("Code-Key", key);
}

[Fact]
public void ShouldThrowForKeyStartingWithSymbol()
{
var exception = Assert.Throws<SnippetReadingException>(() =>
StartEndTester.IsBeginSnippet("<!-- begin-snippet: _key-->", "file", out _));

Approvals.Verify(exception.Message);
}

[Fact]
public void ShouldThrowForKeyEndingWithSymbol()
{
var exception = Assert.Throws<SnippetReadingException>(() =>
StartEndTester.IsBeginSnippet("<!-- begin-snippet: key_ -->", "file", out _));
Approvals.Verify(exception.Message);
}

[Fact]
public void CanExtractWithDifferentEndComments()
{
var isStartCode = StartEndTester.IsBeginSnippet("/* begin-snippet: CodeKey */", "file", out var key);
Assert.True(isStartCode);
Assert.Equal("CodeKey", key);
}

[Fact]
public void CanExtractWithDifferentEndCommentsAndNoSpaces()
{
var isStartCode = StartEndTester.IsBeginSnippet("/*begin-snippet: CodeKey */", "file", out var key);
Assert.True(isStartCode);
Assert.Equal("CodeKey", key);
}

public StartEndTesterIsBeginSnippetTests(ITestOutputHelper output) :
base(output)
{
}
}
2 changes: 1 addition & 1 deletion src/Tests/StartEndTester_IsStartCodeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Xunit;
using Xunit.Abstractions;

public class StartEndTester_IsStartCodeTests :
public class StartEndTester_IsStartCodeTests :
TestBase
{
[Fact]
Expand Down

0 comments on commit 20bedc2

Please sign in to comment.