1.0.0
This commit is contained in:
parent
05a90aee60
commit
1ab6e34449
12 changed files with 315 additions and 1 deletions
44
.gitignore
vendored
44
.gitignore
vendored
|
@ -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
|
||||
|
|
17
.idea/markdown.iml
Normal file
17
.idea/markdown.iml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/markdown.iml" filepath="$PROJECT_DIR$/.idea/markdown.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
7
.idea/runConfigurations/server_dart.xml
Normal file
7
.idea/runConfigurations/server_dart.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="server.dart" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true" nameIsGenerated="true">
|
||||
<option name="filePath" value="$PROJECT_DIR$/example/server.dart" />
|
||||
<option name="workingDirectory" value="$PROJECT_DIR$/example" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
1
.travis.yml
Normal file
1
.travis.yml
Normal file
|
@ -0,0 +1 @@
|
|||
language: dart
|
97
README.md
97
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 '''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>${locals['title']} - My Site</title>
|
||||
</head>
|
||||
<body>
|
||||
$content
|
||||
</body>
|
||||
</html>
|
||||
''';
|
||||
}),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
2
analysis_options.yaml
Normal file
2
analysis_options.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
analyzer:
|
||||
strong-mode: true
|
44
example/server.dart
Normal file
44
example/server.dart
Normal file
|
@ -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<Angel> 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 '''
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<title>${locals['title'] ?? 'Example Site'} - Example Site</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="ui top fixed menu">
|
||||
<a class="header item" href="/">
|
||||
<i class="home icon"></i>
|
||||
Home
|
||||
</a>
|
||||
</div>
|
||||
<div class="ui container" style="margin-top: 5em;">
|
||||
$content
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
''';
|
||||
}));
|
||||
|
||||
// Compile a landing page
|
||||
app.get('/', (res) => res.render('hello', {'title': 'Welcome'}));
|
||||
|
||||
return app;
|
||||
}
|
9
example/views/hello.md
Normal file
9
example/views/hello.md
Normal file
|
@ -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!!!
|
||||
```
|
68
lib/angel_markdown.dart
Normal file
68
lib/angel_markdown.dart
Normal file
|
@ -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<String>`.
|
||||
AngelConfigurer markdown(
|
||||
Directory viewsDirectory, {
|
||||
String extension,
|
||||
ExtensionSet extensionSet,
|
||||
FutureOr<String> 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<String> 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;
|
||||
}
|
13
pubspec.yaml
Normal file
13
pubspec.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
name: angel_markdown
|
||||
version: 1.0.0
|
||||
description: Markdown view generator for Angel.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
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
|
Loading…
Reference in a new issue