├── .gitignore ├── .paket ├── paket.bootstrapper.exe ├── paket.exe └── paket.targets ├── HISTORY.md ├── LICENSE ├── README.md ├── app.config.json ├── app.fsx ├── config.fsx ├── paket.dependencies ├── paket.lock ├── presentations.fsx ├── public └── hello-world.html ├── sample.png ├── src └── helloworld.md └── templates └── presentation.html /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | *.sln.ide/ 9 | 10 | # Xamarin Studio / monodevelop user-specific 11 | *.userprefs 12 | 13 | # Visual Studio and VS Code 14 | /.vs/ 15 | /.vscode/ 16 | .ionide/ 17 | 18 | # Build results 19 | 20 | [Dd]ebug/ 21 | [Rr]elease/ 22 | x64/ 23 | build/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | 27 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 28 | !packages/*/build/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | *_i.c 35 | *_p.c 36 | *.ilk 37 | *.meta 38 | *.obj 39 | *.pch 40 | *.pdb 41 | *.pgc 42 | *.pgd 43 | *.rsp 44 | *.sbr 45 | *.tlb 46 | *.tli 47 | *.tlh 48 | *.tmp 49 | *.tmp_proj 50 | *.log 51 | *.vspscc 52 | *.vssscc 53 | .builds 54 | *.pidb 55 | *.log 56 | *.scc 57 | 58 | # Visual C++ cache files 59 | ipch/ 60 | *.aps 61 | *.ncb 62 | *.opensdf 63 | *.sdf 64 | *.cachefile 65 | 66 | # Visual Studio profiler 67 | *.psess 68 | *.vsp 69 | *.vspx 70 | 71 | # Guidance Automation Toolkit 72 | *.gpState 73 | 74 | # ReSharper is a .NET coding add-in 75 | _ReSharper*/ 76 | *.[Rr]e[Ss]harper 77 | 78 | # TeamCity is a build add-in 79 | _TeamCity* 80 | 81 | # DotCover is a Code Coverage Tool 82 | *.dotCover 83 | 84 | # NCrunch 85 | *.ncrunch* 86 | .*crunch*.local.xml 87 | _NCrunch_* 88 | 89 | # Installshield output folder 90 | [Ee]xpress/ 91 | 92 | # DocProject is a documentation generator add-in 93 | DocProject/buildhelp/ 94 | DocProject/Help/*.HxT 95 | DocProject/Help/*.HxC 96 | DocProject/Help/*.hhc 97 | DocProject/Help/*.hhk 98 | DocProject/Help/*.hhp 99 | DocProject/Help/Html2 100 | DocProject/Help/html 101 | 102 | # Click-Once directory 103 | publish/ 104 | 105 | # Publish Web Output 106 | *.Publish.xml 107 | 108 | # Windows Azure Build Output 109 | csx 110 | *.build.csdef 111 | 112 | # Windows Store app package directory 113 | AppPackages/ 114 | 115 | # Others 116 | sql/ 117 | *.Cache 118 | ClientBin/ 119 | [Ss]tyle[Cc]op.* 120 | ~$* 121 | *~ 122 | *.dbmdl 123 | *.[Pp]ublish.xml 124 | *.pfx 125 | *.publishsettings 126 | project.lock.json 127 | *.binlog 128 | 129 | # RIA/Silverlight projects 130 | Generated_Code/ 131 | 132 | # Backup & report files from converting an old project file to a newer 133 | # Visual Studio version. Backup files are not needed, because we have git ;-) 134 | _UpgradeReport_Files/ 135 | Backup*/ 136 | UpgradeLog*.XML 137 | UpgradeLog*.htm 138 | 139 | # SQL Server files 140 | App_Data/*.mdf 141 | App_Data/*.ldf 142 | 143 | 144 | #LightSwitch generated files 145 | GeneratedArtifacts/ 146 | _Pvt_Extensions/ 147 | ModelManifest.xml 148 | 149 | # ========================= 150 | # Windows detritus 151 | # ========================= 152 | 153 | # Windows image file caches 154 | Thumbs.db 155 | ehthumbs.db 156 | 157 | # Folder config file 158 | Desktop.ini 159 | 160 | # Recycle Bin used on file shares 161 | $RECYCLE.BIN/ 162 | 163 | # Mac desktop service store files 164 | .DS_Store 165 | 166 | # =================================================== 167 | # Exclude F# project specific directories and files 168 | # =================================================== 169 | 170 | # NuGet Packages Directory 171 | packages/ 172 | 173 | # Generated documentation folder 174 | docs/output/ 175 | 176 | # Temp folder used for publishing docs 177 | temp/ 178 | 179 | # Test results produced by build 180 | TestResults.xml 181 | 182 | # Nuget outputs 183 | release.cmd 184 | release.sh 185 | localpackages/ 186 | paket-files 187 | /.paket/load/ 188 | *.orig 189 | docs/content/license.md 190 | docs/content/release-notes.md 191 | _NCrunch_Paket 192 | docs/content/paket-*.md 193 | !docs/content/paket-folder.md 194 | *.bak 195 | System.Management.Automation.dll 196 | .fake 197 | docs/tools/FSharp.Formatting.svclog 198 | docs/content/paket.exe 199 | TestResult.xml 200 | *.trx 201 | tests/Paket.Tests/NuGetConfig/PasswordConfig.xml 202 | paket.local 203 | dotnetcore 204 | .idea 205 | 206 | # For check-doc-links.sh. 207 | node_modules 208 | package-lock.json 209 | 210 | # Enable scenarios in integration tests 211 | !integrationtests/scenarios/*/before/** 212 | integrationtests/scenarios/*/before/**/obj 213 | 214 | # artifacts 215 | /bin_netcore/ 216 | 217 | # Other 218 | scratchpad.fsx -------------------------------------------------------------------------------- /.paket/paket.bootstrapper.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lqdev/RemarkFS/21b8ccfe5abd04924d13dc9ab8e968fba4a63e9a/.paket/paket.bootstrapper.exe -------------------------------------------------------------------------------- /.paket/paket.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lqdev/RemarkFS/21b8ccfe5abd04924d13dc9ab8e968fba4a63e9a/.paket/paket.exe -------------------------------------------------------------------------------- /.paket/paket.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | true 7 | $(MSBuildThisFileDirectory) 8 | $(MSBuildThisFileDirectory)..\ 9 | $(PaketRootPath)paket.lock 10 | $(PaketRootPath)paket-files\paket.restore.cached 11 | /Library/Frameworks/Mono.framework/Commands/mono 12 | mono 13 | 14 | 15 | 16 | 17 | $(PaketRootPath)paket.exe 18 | $(PaketToolsPath)paket.exe 19 | "$(PaketExePath)" 20 | $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" 21 | 22 | 23 | 24 | 25 | 26 | $(MSBuildProjectFullPath).paket.references 27 | 28 | 29 | 30 | 31 | $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references 32 | 33 | 34 | 35 | 36 | $(MSBuildProjectDirectory)\paket.references 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | $(PaketCommand) restore --references-file "$(PaketReferences)" 49 | 50 | RestorePackages; $(BuildDependsOn); 51 | 52 | 53 | 54 | true 55 | 56 | 57 | 58 | $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) 59 | $([System.IO.File]::ReadAllText('$(PaketLockFilePath)')) 60 | true 61 | false 62 | true 63 | 64 | 65 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # 0.0.3 2 | 3 | - Created build pipeline which cleans the build directory and creates fresh Remark presentations from files in the source directory. 4 | 5 | # 0.0.2 6 | 7 | - Allow loading and customization of source/publish directory via a `json` file. 8 | 9 | # 0.0.1 10 | 11 | - Can create presentations using template HTML file. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Luis Quintanilla 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RemarkFS 2 | 3 | FSharp Markdown Slide Creation Tool based on [Remark](https://github.com/gnab/remark) 4 | 5 | ## Dependencies 6 | 7 | - [Mono](https://www.mono-project.com/download/stable/) 8 | - [Fue](https://github.com/Dzoukr/Fue) 9 | - [Fsharp.Formatting](http://fsprojects.github.io/FSharp.Formatting/) 10 | - [Paket](https://fsprojects.github.io/Paket/) 11 | - [Remark](https://github.com/gnab/remark) 12 | - [FAKE](https://fake.build/) 13 | 14 | ## Install 15 | 16 | ```bash 17 | mono .paket/paket.exe install 18 | ``` 19 | 20 | ## Usage 21 | 22 | 23 | ### Create Presentation Content 24 | 25 | Create a new file called `helloworld.md` in the `src` directory 26 | 27 | ```markdown 28 | # Hello World 29 | 30 | --- 31 | 32 | # Agenda 33 | 34 | 1. Introduction 35 | 2. Deep-dive 36 | 3. ... 37 | 38 | --- 39 | 40 | # Introduction 41 | ``` 42 | 43 | ### Build Presentations 44 | 45 | In the console enter 46 | 47 | ```bash 48 | fsharpi app.fsx 49 | ``` 50 | 51 | ### See Presentation 52 | 53 | Once the script is done running, check the `public` folder and you should see a file called `hello-world.html`. Open it in the browser of your choice and the following content should display. 54 | 55 | ![](sample.png) 56 | 57 | ## Configuration 58 | 59 | By default, `Markdown` files are stored in the `src` directory and `Remark` presentations are stored in the `public` directory. To change this, edit the `app.config.json` properties to match the folder of your choosing. 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "source_directory": "./src", 3 | "destination_directory": "./public" 4 | } -------------------------------------------------------------------------------- /app.fsx: -------------------------------------------------------------------------------- 1 | #r "./packages/Fake/tools/FakeLib.dll" 2 | open Fake.Boot 3 | #load "./presentations.fsx" 4 | #load "./config.fsx" 5 | 6 | open Presentations.Operations 7 | open Config 8 | open Fake 9 | open Fake.IO 10 | open System.IO 11 | 12 | let sourcePath = Path.Combine(__SOURCE_DIRECTORY__,Config.getSourceDirectory); 13 | let buildPath = Path.Combine(__SOURCE_DIRECTORY__,Config.getDestionationDirectory) 14 | 15 | Target "Clean" (fun _ -> 16 | Shell.CleanDir buildPath 17 | ) 18 | 19 | Target "Build" (fun _ -> 20 | trace "Building Presentations" 21 | let files = Directory.GetFiles(sourcePath) 22 | writePresentation files 23 | trace "Presentations Built" 24 | ) 25 | 26 | Target "Default" (fun _ -> 27 | trace (sprintf "Source directory cleaned %s" sourcePath) 28 | ) 29 | 30 | "Clean" 31 | ==> "Build" 32 | ==> "Default" 33 | 34 | RunTargetOrDefault "Default" -------------------------------------------------------------------------------- /config.fsx: -------------------------------------------------------------------------------- 1 | #r "./packages/FSharp.Data/lib/net45/FSharp.Data.dll" 2 | 3 | module Config = 4 | 5 | open FSharp.Data 6 | 7 | type Config = JsonProvider<"./app.config.json"> 8 | 9 | let configFile = Config.Load("./app.config.json") 10 | 11 | let getSourceDirectory = 12 | configFile.SourceDirectory 13 | 14 | let getDestionationDirectory = 15 | configFile.DestinationDirectory -------------------------------------------------------------------------------- /paket.dependencies: -------------------------------------------------------------------------------- 1 | source https://www.nuget.org/api/v2 2 | 3 | nuget Fake 4 | nuget FSharp.Data 5 | nuget FSharp.Formatting 6 | nuget Fue 7 | nuget HtmlAgilityPack 1.5.2.0 -------------------------------------------------------------------------------- /presentations.fsx: -------------------------------------------------------------------------------- 1 | #load "./packages/FSharp.Formatting/FSharp.Formatting.fsx" 2 | #r "./packages/HtmlAgilityPack/lib/netstandard2.0/HtmlAgilityPack.dll" 3 | #r "./packages/Fue/lib/netstandard2.0/Fue.dll" 4 | #load "./config.fsx" 5 | 6 | namespace Presentations 7 | open FSharp.Markdown 8 | 9 | type Presentation = {Title:string;Content:MarkdownDocument} 10 | 11 | module Operations = 12 | 13 | open System.Text.RegularExpressions 14 | open System.IO 15 | open Fue.Data 16 | open Fue.Compiler 17 | open Config 18 | let getTitle(line:MarkdownParagraph) = 19 | match line with 20 | | Heading (1,heading) -> 21 | match heading with 22 | | [Literal title] -> title 23 | | _ -> "Title" 24 | | _ -> "No Heading" 25 | 26 | let getIndex (myString:string) = 27 | match myString.Length with 28 | | x when x < 45 -> myString.Length 29 | | _ -> 45 30 | 31 | let getSlug(title:string) = 32 | let lowercase = title.ToLower() 33 | let invalidChars = Regex.Replace(lowercase,@"[^a-z0-9\s-]", "") 34 | let removeMultipleSpaces = Regex.Replace(invalidChars,@"\s+", " ").Trim() 35 | let trimmed = removeMultipleSpaces.Substring(0, (getIndex removeMultipleSpaces)).Trim(); 36 | let hyphenate = Regex.Replace(trimmed, @"\s", "-"); 37 | hyphenate 38 | 39 | let toMarkdown content = 40 | (content,Markdown.Parse content) 41 | 42 | let createPresentation (rawContent:string,content:MarkdownDocument) = 43 | let title = 44 | content.Paragraphs 45 | |> List.map(getTitle) 46 | |> List.filter(fun x -> (x <> "No Heading" && x <> "Title")) 47 | |> List.head 48 | 49 | let presentation = 50 | { Title=title 51 | Content=content } 52 | 53 | (rawContent,presentation) 54 | 55 | let processFile = File.ReadAllText >> toMarkdown >> createPresentation 56 | let writePresentation files = 57 | files 58 | |> Array.map(fun file -> sprintf "%s" file) 59 | |> Array.map processFile 60 | |> List.ofArray 61 | |> List.map(fun (content,presentation) -> content,presentation.Title,presentation.Content) 62 | |> List.map(fun (rawContent,title,content) -> 63 | let filename = sprintf "%s.html" (getSlug title) 64 | let template = __SOURCE_DIRECTORY__ + "/templates/presentation.html" 65 | 66 | let compiledHTML = 67 | init 68 | |> add "title" title 69 | |> add "content" rawContent 70 | |> fromFile template 71 | 72 | File.WriteAllText((sprintf "%s/%s" Config.getDestionationDirectory filename),compiledHTML,System.Text.Encoding.UTF8) 73 | ) -------------------------------------------------------------------------------- /public/hello-world.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Hello World 5 | 6 | 18 | 19 | 20 | 36 | 38 | 43 | 44 | -------------------------------------------------------------------------------- /sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lqdev/RemarkFS/21b8ccfe5abd04924d13dc9ab8e968fba4a63e9a/sample.png -------------------------------------------------------------------------------- /src/helloworld.md: -------------------------------------------------------------------------------- 1 | # Hello World 2 | 3 | --- 4 | 5 | # Agenda 6 | 7 | 1. Introduction 8 | 2. Deep-dive 9 | 3. ... 10 | 11 | --- 12 | 13 | # Introduction -------------------------------------------------------------------------------- /templates/presentation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{{title}}} 5 | 6 | 18 | 19 | 20 | 24 | 26 | 31 | 32 | --------------------------------------------------------------------------------