Add 'packages/markdown/' from commit 'deccd615054c1d5a84071a52d4fe55c50f0f771f'
git-subtree-dir: packages/markdown git-subtree-mainline:8e84218dbe
git-subtree-split:deccd61505
This commit is contained in:
commit
7b33017272
10 changed files with 326 additions and 0 deletions
58
packages/markdown/.gitignore
vendored
Normal file
58
packages/markdown/.gitignore
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# 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/
|
||||||
|
### 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
|
||||||
|
.dart_tool
|
||||||
|
.idea
|
1
packages/markdown/.travis.yml
Normal file
1
packages/markdown/.travis.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
language: dart
|
3
packages/markdown/CHANGELOG.md
Normal file
3
packages/markdown/CHANGELOG.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# 2.0.0
|
||||||
|
* Angel 2 + Dart 2 updates.
|
||||||
|
* Use `package:file`.
|
21
packages/markdown/LICENSE
Normal file
21
packages/markdown/LICENSE
Normal file
|
@ -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.
|
99
packages/markdown/README.md
Normal file
99
packages/markdown/README.md
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# markdown
|
||||||
|
[![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.
|
||||||
|
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.
|
||||||
|
fs.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.
|
||||||
|
fs.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.
|
4
packages/markdown/analysis_options.yaml
Normal file
4
packages/markdown/analysis_options.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
include: package:pedantic/analysis_options.yaml
|
||||||
|
analyzer:
|
||||||
|
strong-mode:
|
||||||
|
implicit-casts: false
|
48
packages/markdown/example/main.dart
Normal file
48
packages/markdown/example/main.dart
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
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 http = AngelHttp(app);
|
||||||
|
var server = await http.startServer(InternetAddress.loopbackIPv4, 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();
|
||||||
|
var fs = LocalFileSystem();
|
||||||
|
await app
|
||||||
|
.configure(markdown(fs.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('/', (req, res) => res.render('hello', {'title': 'Welcome'}));
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
9
packages/markdown/example/views/hello.md
Normal file
9
packages/markdown/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
packages/markdown/lib/angel_markdown.dart
Normal file
68
packages/markdown/lib/angel_markdown.dart
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import 'dart:async';
|
||||||
|
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'@?{{(((\\})|([^}]))+)}}');
|
||||||
|
|
||||||
|
/// 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<String, dynamic> locals),
|
||||||
|
}) {
|
||||||
|
extension ??= '.md';
|
||||||
|
extensionSet ??= ExtensionSet.gitHubWeb;
|
||||||
|
|
||||||
|
return (Angel app) async {
|
||||||
|
app.viewGenerator = (String name, [Map<String, dynamic> locals]) async {
|
||||||
|
var file = viewsDirectory.childFile(
|
||||||
|
viewsDirectory.fileSystem.path.setExtension(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;
|
||||||
|
}
|
15
packages/markdown/pubspec.yaml
Normal file
15
packages/markdown/pubspec.yaml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
name: angel_markdown
|
||||||
|
version: 2.0.0
|
||||||
|
description: Angel Markdown view generator. Write static sites, with no build step.
|
||||||
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
|
homepage: https://github.com/angel-dart/markdown
|
||||||
|
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
|
||||||
|
pedantic: ^1.0.0
|
||||||
|
test: ^1.0.0
|
Loading…
Reference in a new issue