Skip to content

Commit 5beae25

Browse files
committed
add eval of System.Image with inline result
1 parent 06ad938 commit 5beae25

16 files changed

+763
-317
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ The CodeMirror file is from [CodeMirror](https://github.com/marijnh/CodeMirror)
2222

2323
## Changelog
2424

25+
##### 0.2.0
26+
27+
Eval of System.Image with inline result
28+
2529
##### 0.1.0
2630

2731
Eval binding of function and values
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
5+
</startup>
6+
<runtime>
7+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
8+
<dependentAssembly>
9+
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
10+
<bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" />
11+
</dependentAssembly>
12+
</assemblyBinding>
13+
</runtime>
14+
</configuration>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>69eb60a8-7ea7-4365-bfe5-a8ac67fdb174</ProjectGuid>
9+
<OutputType>Exe</OutputType>
10+
<RootNamespace>Examples.Images</RootNamespace>
11+
<AssemblyName>Examples.Images</AssemblyName>
12+
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
13+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
14+
<TargetFSharpCoreVersion>4.3.1.0</TargetFSharpCoreVersion>
15+
<Name>Examples.Images</Name>
16+
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
17+
<RestorePackages>true</RestorePackages>
18+
</PropertyGroup>
19+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
20+
<DebugSymbols>true</DebugSymbols>
21+
<DebugType>full</DebugType>
22+
<Optimize>false</Optimize>
23+
<Tailcalls>false</Tailcalls>
24+
<OutputPath>bin\Debug\</OutputPath>
25+
<DefineConstants>DEBUG;TRACE</DefineConstants>
26+
<WarningLevel>3</WarningLevel>
27+
<PlatformTarget>AnyCPU</PlatformTarget>
28+
<DocumentationFile>bin\Debug\Examples.Images.XML</DocumentationFile>
29+
<Prefer32Bit>true</Prefer32Bit>
30+
</PropertyGroup>
31+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
32+
<DebugType>pdbonly</DebugType>
33+
<Optimize>true</Optimize>
34+
<Tailcalls>true</Tailcalls>
35+
<OutputPath>bin\Release\</OutputPath>
36+
<DefineConstants>TRACE</DefineConstants>
37+
<WarningLevel>3</WarningLevel>
38+
<PlatformTarget>AnyCPU</PlatformTarget>
39+
<DocumentationFile>bin\Release\Examples.Images.XML</DocumentationFile>
40+
<Prefer32Bit>true</Prefer32Bit>
41+
</PropertyGroup>
42+
<ItemGroup>
43+
<Reference Include="mscorlib" />
44+
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
45+
<Private>True</Private>
46+
</Reference>
47+
<Reference Include="System" />
48+
<Reference Include="System.Core" />
49+
<Reference Include="System.Drawing" />
50+
<Reference Include="System.Numerics" />
51+
<Reference Include="System.Windows.Forms" />
52+
</ItemGroup>
53+
<ItemGroup>
54+
<None Include="App.config" />
55+
<None Include="packages.config" />
56+
<Compile Include="GameOfLife.fs" />
57+
<Compile Include="InlineImages.fs" />
58+
</ItemGroup>
59+
<ItemGroup>
60+
<ProjectReference Include="..\..\ltfsclient\ltfsclient.fsproj">
61+
<Name>ltfsclient</Name>
62+
<Project>{70870340-fcfe-472f-8063-770082af204c}</Project>
63+
<Private>True</Private>
64+
</ProjectReference>
65+
</ItemGroup>
66+
<PropertyGroup>
67+
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
68+
</PropertyGroup>
69+
<Choose>
70+
<When Condition="'$(VisualStudioVersion)' == '11.0'">
71+
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
72+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
73+
</PropertyGroup>
74+
</When>
75+
<Otherwise>
76+
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
77+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
78+
</PropertyGroup>
79+
</Otherwise>
80+
</Choose>
81+
<Import Project="$(FSharpTargetsPath)" />
82+
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
83+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
84+
Other similar extension points exist, see Microsoft.Common.targets.
85+
<Target Name="BeforeBuild">
86+
</Target>
87+
<Target Name="AfterBuild">
88+
</Target>
89+
-->
90+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
module LightTable.FSharp.Examples.GameOfLife
2+
3+
open System
4+
open System.Drawing
5+
open System.IO
6+
7+
type Cell =
8+
| Alive
9+
| Dead
10+
11+
let step cell neighbours =
12+
let alives =
13+
neighbours |> List.sumBy (function
14+
| Alive -> 1
15+
| Dead -> 0)
16+
match (cell, alives) with
17+
| Alive, n when n < 2 -> Dead // by under-population
18+
| Alive, n when n > 3 -> Dead // by overcrowding
19+
| Alive, 2 | Alive, 3 -> Alive // lives on
20+
| Dead, 3 -> Alive // by reproduction
21+
| Dead, _ -> Dead
22+
23+
let neighbours getAt (x, y) =
24+
[ for i in [ x - 1..x + 1 ] do
25+
for j in [ y - 1..y + 1 ] -> (i, j) ]
26+
|> List.filter (fun a -> a <> (x, y)) //not itself
27+
|> List.map (fun coord -> (coord, getAt <| coord))
28+
29+
/// World is a Map (x,y) -> Cell with all Alive cell, default is Dead cell
30+
type World = Map<int * int, Cell>
31+
32+
let emptyWorld : World = Map.empty
33+
34+
let getAt coord (world : World) =
35+
match world |> Map.tryFind coord with
36+
| Some x -> x
37+
| None -> Dead
38+
39+
let setAt coord v (world : World) =
40+
match v with
41+
| Alive -> world |> Map.add coord v
42+
| Dead -> world |> Map.remove coord
43+
44+
let tick world =
45+
let at coord = world |> getAt coord
46+
47+
let stepCell (coord, cell) =
48+
let next =
49+
neighbours at coord
50+
|> List.map snd
51+
|> step (at coord)
52+
(coord, next)
53+
54+
let cells = (world |> Map.toSeq)
55+
56+
let potential =
57+
cells
58+
|> Seq.map (fun (coord, _) -> neighbours at coord)
59+
|> Seq.concat
60+
|> Seq.append cells
61+
|> Seq.distinct
62+
potential
63+
|> Seq.map stepCell
64+
|> Seq.fold (fun w (coord, cell) -> w |> setAt coord cell) emptyWorld
65+
66+
let evolution initial =
67+
let some x = if x = emptyWorld then None else Some(x, x)
68+
initial |> Seq.unfold (tick >> some)
69+
70+
// example
71+
let glider =
72+
[ (2, 0), Alive
73+
(0, 1), Alive
74+
(2, 1), Alive
75+
(1, 2), Alive
76+
(2, 2), Alive ]
77+
78+
let add pattern (x, y) world =
79+
let offset (i, j) = x + i, y + j
80+
pattern
81+
|> List.fold (fun w (coord, cell) -> w |> setAt (offset coord) cell) world
82+
83+
// draw
84+
let rec drawWorld (area : Rectangle) cellSize world =
85+
let cells =
86+
seq {
87+
for i in [ area.X..area.Right ] do
88+
for j in [ area.Y..area.Bottom ] -> (i, j)
89+
}
90+
91+
let aliveShape (x, y) =
92+
Rectangle(x * cellSize, y * cellSize, cellSize, cellSize)
93+
cells
94+
|> Seq.map (fun coord -> (coord, world |> getAt coord))
95+
|> Seq.filter (fun (coord, cell) -> cell = Alive)
96+
|> Seq.fold (fun xs (coord, cell) -> aliveShape coord :: xs) []
97+
|> drawImg (area.Right * cellSize) (area.Bottom * cellSize)
98+
99+
and drawImg (width : int) height (rects : Rectangle list) =
100+
let bmp = new Bitmap(width, height)
101+
use g = Graphics.FromImage(bmp)
102+
match rects with
103+
| [] -> ()
104+
| r -> g.FillRectangles(System.Drawing.Brushes.Red, r |> List.toArray)
105+
bmp :> Image
106+
107+
/// plaintext format ( http://www.conwaylife.com/wiki/Plaintext )
108+
let decodePlaintext text =
109+
let data = text |> List.filter (fun (l: string) -> not <| l.StartsWith("!"))
110+
let cell s = if s = "O" then Alive else Dead
111+
let row y d = d |> List.mapi (fun x c -> ((x, y), cell c))
112+
data
113+
|> List.map (fun line -> line.ToCharArray() |> Seq.map (fun x -> x.ToString()) |> Seq.toList)
114+
|> List.mapi (fun y t -> t |> row y)
115+
|> List.concat
116+
|> List.fold (fun w (coord, c) -> w |> setAt coord c) emptyWorld
117+
118+
let downloadPattern name =
119+
use client = new System.Net.WebClient()
120+
let url = sprintf "http://www.conwaylife.com/patterns/%s.cells" name
121+
client.DownloadString(Uri(url))
122+
|> (fun x -> x.Split('\n') |> Seq.toList)
123+
|> decodePlaintext
124+
125+
let glider2 () = downloadPattern <| "glider"
126+
let baker () = downloadPattern <| "baker"
127+
let gosperglidergun () = downloadPattern <| "gosperglidergun"
128+
129+
// let's try
130+
let run times world =
131+
world
132+
|> evolution
133+
|> Seq.zip [ 0..times ]
134+
|> Seq.map snd
135+
136+
let sample = emptyWorld |> add glider (0, 0)
137+
138+
open LightTable.FSharp.Inspector.Helpers
139+
140+
let gif initial =
141+
[ initial ]
142+
|> Seq.append (initial |> run 60)
143+
|> Seq.map (drawWorld (Rectangle(0, 0, 40, 40)) 25)
144+
|> Gif.create (TimeSpan.FromSeconds(0.2))
145+
146+
147+
gosperglidergun () |> gif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module LightTable.FSharp.Examples.InlineImages
2+
3+
open System
4+
open System.Drawing
5+
6+
let download url =
7+
use client = new Net.WebClient()
8+
let data = client.DownloadData(Uri(url))
9+
use stream = new IO.MemoryStream(data)
10+
Image.FromStream(stream)
11+
12+
let thumb (img : Image) =
13+
img.GetThumbnailImage(150, 150, (fun () -> false), IntPtr.Zero)
14+
15+
let get = download >> thumb
16+
17+
let imageGraphics() =
18+
let shape =
19+
let path = new Drawing2D.GraphicsPath()
20+
path.AddArc(10, 10, 150, 150, 135.0f, 195.0f)
21+
path.AddArc(140, 10, 150, 150, 210.0f, 195.0f)
22+
path.AddLine(32, 139, 150, 270)
23+
path.AddLine(267, 139, 150, 270)
24+
path.AddLine(267, 139, 32, 139)
25+
path
26+
27+
let bmp = new Bitmap(300, 300)
28+
use g = Graphics.FromImage(bmp)
29+
g.FillPath(Brushes.Red, shape)
30+
g.DrawPath(Pens.Red, shape)
31+
bmp
32+
33+
let lt = get <| "http://www.lighttable.com/img/logo.png"
34+
35+
let love = imageGraphics() |> thumb
36+
37+
let fsharp = get <| "http://fsharp.org/img/logo.png"
38+
39+
let gif = download <| "http://optimalhumanmodulation.files.wordpress.com/2013/11/heroics.gif"
40+
41+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
</packages>

fs-src/ltfsclient.Tests/Library1.fs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module ltfsclient.Tests
1+
module LightTable.FSharp.Tests.FSI
22
//
33
//open System
44
//open System.IO

fs-src/ltfsclient.Tests/LightTable.fs

+22-13
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,30 @@
33
open System
44
open NUnit.Framework
55
open FsUnit
6-
7-
open LtFsClient.LightTableInterop
6+
open LightTable.FSharp.LightTableInterop
87

98
[<TestFixture>]
10-
type ``parse commands`` () =
11-
9+
type ``parse commands``() =
10+
1211
[<Test>]
13-
member x.``eval selected`` () =
14-
let cmd = """[345,"editor.eval.fsharp", {"line-ending":null,"name":"test.fs","type-name":"FSharp","path":"C:\\path\\to\\project\\test.fs","mime":"text/x-fsharp","tags":["editor.fsharp"],"code":"1 + 4","meta":{"start":10,"end":15}}]"""
15-
let arg = {LineEnding=None; Name="test.fs"; TypeName="FSharp"; Path="C:\\path\\to\\project\\test.fs"; Mime="text/x-fsharp"; Tags=["editor.fsharp"]; Code="1 + 4"; Meta= Some (10,15); Pos=None}
16-
parseRequest cmd |> should equal (Valid(345,Eval(arg)))
17-
12+
member x.``eval selected``() =
13+
let cmd =
14+
"""[345,"editor.eval.fsharp", {"line-ending":null,"name":"test.fs","type-name":"FSharp","path":"C:\\path\\to\\project\\test.fs","mime":"text/x-fsharp","tags":["editor.fsharp"],"code":"1 + 4","meta":{"start":10,"end":15}}]"""
15+
16+
let arg =
17+
{ LineEnding = None
18+
Name = "test.fs"
19+
TypeName = "FSharp"
20+
Path = "C:\\path\\to\\project\\test.fs"
21+
Mime = "text/x-fsharp"
22+
Tags = [ "editor.fsharp" ]
23+
Code = "1 + 4"
24+
Meta = Some(10, 15)
25+
Pos = None }
26+
parseRequest cmd |> should equal (Valid(345, Eval(arg)))
27+
1828
[<Test>]
19-
member x.``close`` () =
29+
member x.close() =
2030
let cmd = """ [345,"client.close",null] """
21-
parseRequest cmd |> should equal (Valid(345,Close))
22-
23-
//[53,"editor.eval.fsharp",{"line-ending":null,"name":"test.fs","type-name":"F#","path":"C:\\github\\LightTable-FSharp\\fs-src\\test\\test.fs","mime":"text/x-fsharp","tags":["editor.fsharp"],"pos":{"line":2,"ch":0},"code":"1 + 4\n\nSystem.DateTime.Now\n\nArray.create 12 (byte 0)\n\n[0..2..10]\n\nlet add x y = x + y + 10\n\nadd 1 3\n"}]
31+
parseRequest cmd |> should equal (Valid(345, Close))
32+
//[53,"editor.eval.fsharp",{"line-ending":null,"name":"test.fs","type-name":"F#","path":"C:\\github\\LightTable-FSharp\\fs-src\\test\\test.fs","mime":"text/x-fsharp","tags":["editor.fsharp"],"pos":{"line":2,"ch":0},"code":"1 + 4\n\nSystem.DateTime.Now\n\nArray.create 12 (byte 0)\n\n[0..2..10]\n\nlet add x y = x + y + 10\n\nadd 1 3\n"}]

0 commit comments

Comments
 (0)