From 05a90aee60f1c0fdefbde3c7eabe4817c1cf30bf Mon Sep 17 00:00:00 2001 From: Tobe O Date: Sat, 12 Aug 2017 23:31:31 -0400 Subject: [PATCH 1/6] Initial commit --- .gitignore | 12 ++++++++++++ LICENSE | 21 +++++++++++++++++++++ README.md | 2 ++ 3 files changed, 35 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..4d2a4d6d --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# See https://www.dartlang.org/tools/private-files.html + +# Files and directories created by pub +.packages +.pub/ +build/ +# If you're building an application, you may want to check-in your pubspec.lock +pubspec.lock + +# Directory created by dartdoc +# If you don't generate documentation locally you can remove this line. +doc/api/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..89074fd3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 The Angel Framework + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..239792a6 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# markdown +Markdown view generator for Angel. From 1ab6e344491d9c55f016049fed3ba31cdb994ec2 Mon Sep 17 00:00:00 2001 From: thosakwe Date: Sun, 13 Aug 2017 00:24:38 -0400 Subject: [PATCH 2/6] 1.0.0 --- .gitignore | 44 +++++++++++ .idea/markdown.iml | 17 +++++ .idea/modules.xml | 8 ++ .idea/runConfigurations/server_dart.xml | 7 ++ .idea/vcs.xml | 6 ++ .travis.yml | 1 + README.md | 97 ++++++++++++++++++++++++- analysis_options.yaml | 2 + example/server.dart | 44 +++++++++++ example/views/hello.md | 9 +++ lib/angel_markdown.dart | 68 +++++++++++++++++ pubspec.yaml | 13 ++++ 12 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 .idea/markdown.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/runConfigurations/server_dart.xml create mode 100644 .idea/vcs.xml create mode 100644 .travis.yml create mode 100644 analysis_options.yaml create mode 100644 example/server.dart create mode 100644 example/views/hello.md create mode 100644 lib/angel_markdown.dart create mode 100644 pubspec.yaml diff --git a/.gitignore b/.gitignore index 4d2a4d6d..99e7978e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,47 @@ pubspec.lock # Directory created by dartdoc # If you don't generate documentation locally you can remove this line. doc/api/ +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties diff --git a/.idea/markdown.iml b/.idea/markdown.iml new file mode 100644 index 00000000..1b1acc21 --- /dev/null +++ b/.idea/markdown.iml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..f3cfa2fd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/server_dart.xml b/.idea/runConfigurations/server_dart.xml new file mode 100644 index 00000000..5f6f2d5a --- /dev/null +++ b/.idea/runConfigurations/server_dart.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..de2210c9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: dart \ No newline at end of file diff --git a/README.md b/README.md index 239792a6..b3f0284b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,97 @@ # markdown -Markdown view generator for Angel. +[![Pub](https://img.shields.io/pub/v/angel_markdown.svg)](https://pub.dartlang.org/packages/angel_markdown) + +Markdown view generator for Angel. + +With this plug-in, you can easily serve +static sites without doing more than writing simple Markdown. Thus, it is a friendly +choice for writing API documentation or other tedious HTML-writing tasks. + +# Installation +In your `pubspec.yaml`: + +```yaml +dependencies: + angel_framework: ^1.0.0 + angel_markdown: ^1.0.0 +``` + +# Usage +It's very straightforward to configure an Angel server to use Markdown: + +```dart +configureServer(Angel app) async { + await app.configure(markdown( + // The directory where your views are located. + new Directory('views'), + )); +} +``` + +You can then generate HTML on-the-fly in a request handler. +Assuming your view directory contained a file named `hello.md`, the +following would render it as an HTML response: + +```dart +configureServer(Angel app) async { + app.get('/hello', (res) => res.render('hello')); +} +``` + +`package:angel_markdown` by default searches for files with a `.md` extension; however, +you can easily override this. + +## Interpolation +`angel_markdown` can interpolate the values of data from `locals` before building the Markdown. + +For example, with the following template `species.md`: + +```markdown +# Species: {{species.name}} +The species *{{species.genus.name}} {{species.name}}* is fascinating... +``` + +You can render as follows: + +```dart +requestHandler(ResponseContext res) { + return res.render('species', { + 'species': new Species('sapiens', genius: 'homo') + }); +} +``` + +To disable interpolation for a single bracket, prefix it with an `@`, ex: `@{{raw | not_interpolated | angular}}`. + +## Templates +Markdown is frequently used to build the *content* of sites, but not the templates. +You might want to wrap the content of pages in a custom template to apply pretty +CSS and JS, etc: + +```dart +configureServer(Angel app) async { + await app.configure( + markdown( + // The directory where your views are located. + new Directory('views'), template: (content, Map locals) { + return ''' + + + ${locals['title']} - My Site + + + $content + + + '''; + }), + ); +} +``` + +The `template` function will have access to whatever values were passed to the renderer, +or an empty `Map`. + +## Enhancing Markdown +You can pass an `extensionSet` to add additional features to the Markdown renderer. +By default, this plug-in configures it to enable Github-flavored Markdown. \ No newline at end of file diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 00000000..518eb901 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,2 @@ +analyzer: + strong-mode: true \ No newline at end of file diff --git a/example/server.dart b/example/server.dart new file mode 100644 index 00000000..f400fd39 --- /dev/null +++ b/example/server.dart @@ -0,0 +1,44 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:angel_framework/angel_framework.dart'; +import 'package:angel_markdown/angel_markdown.dart'; + +main() async { + var app = await createServer(); + var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 3000); + print('Listening at http://${server.address.address}:${server.port}'); +} + +Future createServer() async { + // Create a new server, and install the Markdown renderer. + var app = new Angel(); + await app + .configure(markdown(new Directory('views'), template: (content, locals) { + return ''' + + + + + ${locals['title'] ?? 'Example Site'} - Example Site + + + + +
+ $content +
+ + + '''; + })); + + // Compile a landing page + app.get('/', (res) => res.render('hello', {'title': 'Welcome'})); + + return app; +} diff --git a/example/views/hello.md b/example/views/hello.md new file mode 100644 index 00000000..6c46de8d --- /dev/null +++ b/example/views/hello.md @@ -0,0 +1,9 @@ +# Welcome +Welcome to a *simple* Markdown-gen site! + +Do you mind **starring** the +[Angel repository](https://github.com/angel-dart/angel)? + +``` +Look, a code block!!! +``` \ No newline at end of file diff --git a/lib/angel_markdown.dart b/lib/angel_markdown.dart new file mode 100644 index 00000000..314090f9 --- /dev/null +++ b/lib/angel_markdown.dart @@ -0,0 +1,68 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:mirrors'; +import 'package:angel_framework/angel_framework.dart'; +import 'package:markdown/markdown.dart'; + +final RegExp _braces = new RegExp(r'@?{{((\\})|([^}]))+}}'); + +/// Configures an [Angel] instance to render Markdown templates from the specified [viewsDirectory]. +/// +/// The default [extension] is `.md`. To search for a different file extension, provide a new one. +/// By default, an [extensionSet] is provided that renders Github-flavored Markdown. This can also be overridden. +/// +/// In many cases, Markdown content will be rendered within a larger [template] that styles the entire website. +/// To wrap generated Markdown content in a template, provide a function that accepts a generated HTML String, +/// and returns a String, or a `Future`. +AngelConfigurer markdown( + Directory viewsDirectory, { + String extension, + ExtensionSet extensionSet, + FutureOr template(String content, Map locals), +}) { + extension ??= '.md'; + extensionSet ?? ExtensionSet.gitHub; + + return (Angel app) async { + app.viewGenerator = (String name, [Map locals]) async { + var file = + new File.fromUri(viewsDirectory.uri.resolve('$name$extension')); + var contents = await file.readAsString(); + + contents = contents.replaceAllMapped(_braces, (m) { + var text = m[0]; + + if (text.startsWith('@')) { + // Raw braces + return text.substring(1); + } else { + var expr = m[1]; + var split = expr.split('.'); + var root = split[0]; + + if (!locals?.containsKey(root) == true) + throw new UnimplementedError( + 'Expected a local named "$root", but none was provided. Expression text: "$text"'); + + return _resolveDotNotation(split, locals[root]).toString(); + } + }); + + var html = markdownToHtml(contents, extensionSet: extensionSet); + if (template != null) html = await template(html, locals ?? {}); + return html; + }; + }; +} + +_resolveDotNotation(List split, target) { + if (split.length == 1) return target; + + InstanceMirror mirror = reflect(target); + + for (int i = 1; i < split.length; i++) { + mirror = mirror.getField(new Symbol(split[i])); + } + + return mirror.reflectee; +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 00000000..f1e327d6 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,13 @@ +name: angel_markdown +version: 1.0.0 +description: Markdown view generator for Angel. +author: Tobe O +homepage: https://github.com/angel-dart/markdown +environment: + sdk: ">=1.19.0" +dependencies: + angel_framework: ^1.0.0 + markdown: ^0.11.4 +dev_dependencies: + angel_test: ^1.0.0 + test: ^0.12.0 \ No newline at end of file From dc5fd569bcf9639cd818bc68edf06f9d2b03270a Mon Sep 17 00:00:00 2001 From: thosakwe Date: Sun, 13 Aug 2017 15:42:29 -0400 Subject: [PATCH 3/6] Fixed minor bugs --- .idea/markdown.iml | 2 ++ lib/angel_markdown.dart | 4 ++-- pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.idea/markdown.iml b/.idea/markdown.iml index 1b1acc21..372e7bf8 100644 --- a/.idea/markdown.iml +++ b/.idea/markdown.iml @@ -5,6 +5,8 @@ + + diff --git a/lib/angel_markdown.dart b/lib/angel_markdown.dart index 314090f9..a8412ecc 100644 --- a/lib/angel_markdown.dart +++ b/lib/angel_markdown.dart @@ -4,7 +4,7 @@ import 'dart:mirrors'; import 'package:angel_framework/angel_framework.dart'; import 'package:markdown/markdown.dart'; -final RegExp _braces = new RegExp(r'@?{{((\\})|([^}]))+}}'); +final RegExp _braces = new RegExp(r'@?{{(((\\})|([^}]))+)}}'); /// Configures an [Angel] instance to render Markdown templates from the specified [viewsDirectory]. /// @@ -21,7 +21,7 @@ AngelConfigurer markdown( FutureOr template(String content, Map locals), }) { extension ??= '.md'; - extensionSet ?? ExtensionSet.gitHub; + extensionSet ??= ExtensionSet.gitHub; return (Angel app) async { app.viewGenerator = (String name, [Map locals]) async { diff --git a/pubspec.yaml b/pubspec.yaml index f1e327d6..4342069b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_markdown -version: 1.0.0 +version: 1.0.0+1 description: Markdown view generator for Angel. author: Tobe O homepage: https://github.com/angel-dart/markdown From 9d227960005c185d3d41fa3bbd69bc7eab7dbfcf Mon Sep 17 00:00:00 2001 From: Tobe O Date: Thu, 11 Apr 2019 12:05:27 -0400 Subject: [PATCH 4/6] Update pubspec, remove idea --- .idea/markdown.iml | 19 ------------------- .idea/modules.xml | 8 -------- .idea/runConfigurations/server_dart.xml | 7 ------- .idea/vcs.xml | 6 ------ 4 files changed, 40 deletions(-) delete mode 100644 .idea/markdown.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/runConfigurations/server_dart.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/markdown.iml b/.idea/markdown.iml deleted file mode 100644 index 372e7bf8..00000000 --- a/.idea/markdown.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index f3cfa2fd..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/server_dart.xml b/.idea/runConfigurations/server_dart.xml deleted file mode 100644 index 5f6f2d5a..00000000 --- a/.idea/runConfigurations/server_dart.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 5fdad82fee20f75d8a7e2d61fd7c4627f7c173d3 Mon Sep 17 00:00:00 2001 From: Tobe O Date: Thu, 11 Apr 2019 12:05:33 -0400 Subject: [PATCH 5/6] CHANGELOG for 2.0 bump --- .gitignore | 2 ++ CHANGELOG.md | 2 ++ pubspec.yaml | 15 ++++++++------- 3 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.gitignore b/.gitignore index 99e7978e..240b46ab 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties +.dart_tool +.idea \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..324effd8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2 @@ +# 2.0.0 +* Angel 2 + Dart 2 updates. \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 4342069b..49d669b5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,13 +1,14 @@ name: angel_markdown -version: 1.0.0+1 -description: Markdown view generator for Angel. +version: 2.0.0 +description: Angel Markdown view generator. Write static sites, with no build step. author: Tobe O homepage: https://github.com/angel-dart/markdown environment: - sdk: ">=1.19.0" + sdk: ">=2.0.0-dev <3.0.0" dependencies: - angel_framework: ^1.0.0 - markdown: ^0.11.4 + angel_framework: ^2.0.0-alpha + markdown: ^2.0.0 dev_dependencies: - angel_test: ^1.0.0 - test: ^0.12.0 \ No newline at end of file + angel_test: ^2.0.0 + pedantic: ^1.0.0 + test: ^1.0.0 From deccd615054c1d5a84071a52d4fe55c50f0f771f Mon Sep 17 00:00:00 2001 From: Tobe O Date: Thu, 11 Apr 2019 12:19:12 -0400 Subject: [PATCH 6/6] 2.0.0 --- CHANGELOG.md | 3 ++- README.md | 8 +++++--- analysis_options.yaml | 4 +++- example/{server.dart => main.dart} | 10 +++++++--- lib/angel_markdown.dart | 14 +++++++------- pubspec.yaml | 1 + 6 files changed, 25 insertions(+), 15 deletions(-) rename example/{server.dart => main.dart} (75%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 324effd8..4f34420a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,3 @@ # 2.0.0 -* Angel 2 + Dart 2 updates. \ No newline at end of file +* Angel 2 + Dart 2 updates. +* Use `package:file`. \ No newline at end of file diff --git a/README.md b/README.md index b3f0284b..fcbe1274 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,15 @@ dependencies: ``` # Usage -It's very straightforward to configure an Angel server to use Markdown: +It's very straightforward to configure an Angel server to use Markdown. +Keep in mind to use `package:file` instead of `dart:io`: ```dart configureServer(Angel app) async { + var fs = LocalFileSystem(); await app.configure(markdown( // The directory where your views are located. - new Directory('views'), + fs.directory('views'), )); } ``` @@ -73,7 +75,7 @@ configureServer(Angel app) async { await app.configure( markdown( // The directory where your views are located. - new Directory('views'), template: (content, Map locals) { + fs.directory('views'), template: (content, Map locals) { return ''' diff --git a/analysis_options.yaml b/analysis_options.yaml index 518eb901..c230cee7 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,2 +1,4 @@ +include: package:pedantic/analysis_options.yaml analyzer: - strong-mode: true \ No newline at end of file + strong-mode: + implicit-casts: false \ No newline at end of file diff --git a/example/server.dart b/example/main.dart similarity index 75% rename from example/server.dart rename to example/main.dart index f400fd39..b1525717 100644 --- a/example/server.dart +++ b/example/main.dart @@ -1,19 +1,23 @@ import 'dart:async'; import 'dart:io'; import 'package:angel_framework/angel_framework.dart'; +import 'package:angel_framework/http.dart'; import 'package:angel_markdown/angel_markdown.dart'; +import 'package:file/local.dart'; main() async { var app = await createServer(); - var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 3000); + var http = AngelHttp(app); + var server = await http.startServer(InternetAddress.loopbackIPv4, 3000); print('Listening at http://${server.address.address}:${server.port}'); } Future createServer() async { // Create a new server, and install the Markdown renderer. var app = new Angel(); + var fs = LocalFileSystem(); await app - .configure(markdown(new Directory('views'), template: (content, locals) { + .configure(markdown(fs.directory('views'), template: (content, locals) { return ''' @@ -38,7 +42,7 @@ Future createServer() async { })); // Compile a landing page - app.get('/', (res) => res.render('hello', {'title': 'Welcome'})); + app.get('/', (req, res) => res.render('hello', {'title': 'Welcome'})); return app; } diff --git a/lib/angel_markdown.dart b/lib/angel_markdown.dart index a8412ecc..86bab23c 100644 --- a/lib/angel_markdown.dart +++ b/lib/angel_markdown.dart @@ -1,7 +1,7 @@ import 'dart:async'; -import 'dart:io'; import 'dart:mirrors'; import 'package:angel_framework/angel_framework.dart'; +import 'package:file/file.dart'; import 'package:markdown/markdown.dart'; final RegExp _braces = new RegExp(r'@?{{(((\\})|([^}]))+)}}'); @@ -18,15 +18,15 @@ AngelConfigurer markdown( Directory viewsDirectory, { String extension, ExtensionSet extensionSet, - FutureOr template(String content, Map locals), + FutureOr template(String content, Map locals), }) { extension ??= '.md'; - extensionSet ??= ExtensionSet.gitHub; + extensionSet ??= ExtensionSet.gitHubWeb; return (Angel app) async { - app.viewGenerator = (String name, [Map locals]) async { - var file = - new File.fromUri(viewsDirectory.uri.resolve('$name$extension')); + app.viewGenerator = (String name, [Map locals]) async { + var file = viewsDirectory.childFile( + viewsDirectory.fileSystem.path.setExtension(name, extension)); var contents = await file.readAsString(); contents = contents.replaceAllMapped(_braces, (m) { @@ -40,7 +40,7 @@ AngelConfigurer markdown( var split = expr.split('.'); var root = split[0]; - if (!locals?.containsKey(root) == true) + if (locals?.containsKey(root) != true) throw new UnimplementedError( 'Expected a local named "$root", but none was provided. Expression text: "$text"'); diff --git a/pubspec.yaml b/pubspec.yaml index 49d669b5..13035656 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,6 +7,7 @@ environment: sdk: ">=2.0.0-dev <3.0.0" dependencies: angel_framework: ^2.0.0-alpha + file: ^5.0.0 markdown: ^2.0.0 dev_dependencies: angel_test: ^2.0.0