Skip to content

Commit

Permalink
Fixes a bug/crash when a fenced code block starts with an empty line
Browse files Browse the repository at this point in the history
- Fixes the bug (only remove the line-ending character when
  FSharp.Formatting commands are found).
- Upgrades some missing projects to net45 (because the bugfix contains
  logging which is in FSharp.Formatting.Common, which in itself is build
  for net45)
  • Loading branch information
matthid committed Dec 17, 2015
1 parent a6c8f16 commit 1f5b279
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 43 deletions.
20 changes: 20 additions & 0 deletions src/Common/StringParsing.fs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,26 @@ module String =
if n = 0 || n % repeated.Length <> 0 then None
else Some(n/repeated.Length, text.Substring(n, text.Length - n))

/// Ignores everything until a end-line character is detected, returns the remaining string.
let (|SkipSingleLine|) (text:string) =
let rec tryEol eolList =
match eolList with
| h : string :: t ->
match text.IndexOf(h) with
| i when i < 0 -> tryEol t
| i ->
text.Substring (i + h.Length)
| _ ->
text
let result = tryEol [ "\r\n"; "\n" ]
let skipped = text.Substring(0, text.Length - result.Length)
if not <| String.IsNullOrWhiteSpace(skipped) then
FSharp.Formatting.Common.Log.warnf "skipped '%s' which contains non-whitespace character!" skipped
if result = text then
FSharp.Formatting.Common.Log.warnf "could not skip a line of %s, because no line-ending character was found!" text
result


/// Matches when a string starts with a sub-string wrapped using the
/// opening and closing sub-string specified in the parameter.
/// For example "[aa]bc" is wrapped in [ and ] pair. Returns the wrapped
Expand Down
7 changes: 7 additions & 0 deletions src/FSharp.CodeFormat/FSharp.CodeFormat.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@
<Reference Include="System.Numerics" />
<Reference Include="System.Web" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FSharp.Formatting.Common\FSharp.Formatting.Common.fsproj">
<Name>FSharp.Formatting.Common</Name>
<Project>{91bad90e-bf3b-4646-a1a7-1568f8f25075}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
Expand Down
10 changes: 3 additions & 7 deletions src/FSharp.Literate/Transformations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ module Transformations =
/// to colorize. We skip snippets that specify non-fsharp langauge e.g. [lang=csharp].
let rec collectCodeSnippets par = seq {
match par with
| CodeBlock((String.StartsWithWrapped ("[", "]") (ParseCommands cmds, String.TrimStart code)), language, _)
| CodeBlock((String.StartsWithWrapped ("[", "]") (ParseCommands cmds, String.SkipSingleLine code)), language, _)
when (not (String.IsNullOrWhiteSpace(language)) && language <> "fsharp") || (cmds.ContainsKey("lang") && cmds.["lang"] <> "fsharp") -> ()
| CodeBlock((String.StartsWithWrapped ("[", "]") (ParseCommands cmds, String.TrimStart code)), _, _)
| CodeBlock((String.StartsWithWrapped ("[", "]") (ParseCommands cmds, String.SkipSingleLine code)), _, _)
| CodeBlock(Let (dict []) (cmds, code), _, _) ->
let modul =
match cmds.TryGetValue("module") with
Expand All @@ -39,12 +39,8 @@ module Transformations =
/// Replace CodeBlock elements with formatted HTML that was processed by the F# snippets tool
/// (The dictionary argument is a map from original code snippets to formatted HTML snippets.)
let rec replaceCodeSnippets path (codeLookup:IDictionary<_, _>) = function
| CodeBlock ((String.StartsWithWrapped ("[", "]") (ParseCommands cmds, code)), language, _)
| CodeBlock ((String.StartsWithWrapped ("[", "]") (ParseCommands cmds, String.SkipSingleLine code)), language, _)
| CodeBlock(Let (dict []) (cmds, code), language, _) ->
let code =
if code.StartsWith("\r\n") then code.Substring(2)
elif code.StartsWith("\n") then code.Substring(1)
else code
if cmds.ContainsKey("hide") then None else
let code =
if cmds.ContainsKey("file") && cmds.ContainsKey("key") then
Expand Down
11 changes: 9 additions & 2 deletions src/FSharp.Markdown/FSharp.Markdown.fsproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand All @@ -10,7 +10,7 @@
<RootNamespace>FSharp.Markdown</RootNamespace>
<AssemblyName>
</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<Name>FSharp.Markdown</Name>
Expand Down Expand Up @@ -64,6 +64,13 @@
<Compile Include="LatexFormatting.fs" />
<Compile Include="Main.fs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FSharp.Formatting.Common\FSharp.Formatting.Common.fsproj">
<Name>FSharp.Formatting.Common</Name>
<Project>{91bad90e-bf3b-4646-a1a7-1568f8f25075}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
Expand Down
41 changes: 41 additions & 0 deletions tests/FSharp.Literate.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,19 @@ let test = 42
doc.Paragraphs |> shouldMatchPar (function
| Paragraph [Strong [Literal "hello"]] -> true | _ -> false)

[<Test>]
let ``Can parse and format markdown with Github-flavoured F# snippet starting and ending with empty lines`` () =
let content = """
```fsharp
let test = 42
```"""
let doc = Literate.ParseMarkdownString(content, formatAgent = getFormatAgent())
doc.Errors |> Seq.length |> shouldEqual 0
doc.Paragraphs |> shouldMatchPar (function
| Matching.LiterateParagraph(FormattedCode(_)) -> true | _ -> false)

[<Test>]
let ``Can generate references from indirect links`` () =
let content = """
Expand Down Expand Up @@ -206,6 +219,34 @@ let ``Correctly handles Norwegian letters in SQL code block (#249)`` () =
let html = Literate.WriteHtml(doc)
html |> should contain ">Æøå<"

[<Test>]
let ``Correctly handles code starting with whitespace`` () =
let content = """
[lang=unknown]
inner"""
let doc = Literate.ParseMarkdownString(content, formatAgent=getFormatAgent())
let html = Literate.WriteHtml(doc)
html |> should contain "> inner<"

[<Test>]
let ``Correctly handles code which garbage after commands`` () =
// This will trigger a warning!
let content = """
[lang=unknown] some ignored garbage
inner"""
let doc = Literate.ParseMarkdownString(content, formatAgent=getFormatAgent())
let html = Literate.WriteHtml(doc)
html |> should contain "> inner<"

[<Test>]
let ``Correctly handles code after the commands`` () =
// This will work, but trigger a warning!
let content = """
[lang=unknown] let this be some code"""
let doc = Literate.ParseMarkdownString(content, formatAgent=getFormatAgent())
let html = Literate.WriteHtml(doc)
html |> should contain " let this be some code"

[<Test>]
let ``Correctly handles apostrophes in JS code block (#213)`` () =
let content = """
Expand Down
66 changes: 33 additions & 33 deletions tests/FSharp.Markdown.Tests/App.config
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="4.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="4.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0-4.3.0.0" newVersion="4.3.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="CommandLine" publicKeyToken="de6f01bd326f8c32" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.9.71.2" newVersion="1.9.71.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.4.14350" newVersion="2.6.4.14350" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="RazorEngine" publicKeyToken="9ee697374c7e744a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.3.0.0" />
</dependentAssembly>
</assemblyBinding></runtime>
</configuration>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="4.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="4.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0-4.3.0.0" newVersion="4.3.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="CommandLine" publicKeyToken="de6f01bd326f8c32" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.9.71.2" newVersion="1.9.71.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.4.14350" newVersion="2.6.4.14350" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="RazorEngine" publicKeyToken="9ee697374c7e744a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
2 changes: 1 addition & 1 deletion tests/FSharp.Markdown.Tests/FSharp.Markdown.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<OutputType>Library</OutputType>
<RootNamespace>FSharp.Markdown.Tests</RootNamespace>
<AssemblyName>FSharp.Markdown.Tests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<Name>FSharp.Markdown.Tests</Name>
Expand Down

0 comments on commit 1f5b279

Please sign in to comment.