-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3613b79
Showing
6 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.dub | ||
docs.json | ||
__dummy.html | ||
*.o | ||
*.obj | ||
__test__*__ | ||
*.html | ||
*.dwt | ||
dwttool | ||
dub.selections.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Copyright 2017 Martin Muehlbauer | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
dwttool - A tool to manage websites based on Dynamic Web Templates | ||
================================================================== | ||
|
||
![dwttool logo](dwttool-logo.jpg) | ||
|
||
About | ||
----- | ||
A couple of years ago I created several websites with Microsoft's tool Expression Web. I loved Expression Web because it had a decent HTML/CSS editor and a cool feature called DWT - Dynamic Web Templates (similar to those in Adobe's Dreamweaver). Unfortunately Expression Web only runs on Windows. dwttool is a command line tool that tries to fill this gap. With dwttool you can create new projects based on DWT and manage existing ones on Linux. dwttool is written in the [D programming language](https://dlang.org/ "D programming language"). | ||
|
||
Download | ||
-------- | ||
The latest binaries are available on [https://github.com/kambrium/dwttool/releases](https://github.com/kambrium/dwttool/releases "https://github.com/kambrium/dwttool/releases"). | ||
|
||
Installation | ||
------------ | ||
Add the directory that contains the dwttool binary to your PATH. For example, on Ubuntu, add the following line to your `.bashrc`. | ||
``` | ||
export PATH=$PATH:/this/is/your/dwttool/path/ | ||
``` | ||
|
||
Getting started | ||
--------------- | ||
```shell | ||
// Let's create a new project | ||
$ dwttool create project my_cool_website | ||
$ cd my_cool_website | ||
// Edit the template | ||
$ vim master.dwt | ||
// Create new HTML file from template | ||
$ dwttool create page index.html master.dwt | ||
// Run the server on port 50000 | ||
$ dwttool serve | ||
``` | ||
License | ||
------- | ||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "dwttool", | ||
"authors": [ | ||
"Martin Muehlbauer" | ||
], | ||
"description": "A tool to manage websites based on Dynamic Web Templates", | ||
"copyright": "Copyright © 2017, Martin Muehlbauer", | ||
"license": "MIT", | ||
"dependencies": { | ||
"vibe-d": "~>0.8.0-beta.5" | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
import core.exception; | ||
import core.stdc.stdlib; | ||
import std.algorithm; | ||
import std.file; | ||
import std.format; | ||
import std.path; | ||
import std.range; | ||
import std.regex; | ||
import std.stdio; | ||
import vibe.core.core; | ||
import vibe.http.fileserver; | ||
import vibe.http.router; | ||
import vibe.http.server; | ||
|
||
// Constants | ||
private | ||
{ | ||
enum ver = "0.1.0"; | ||
|
||
enum invalidArgumentError = "ERROR: No or invalid argument(s) given. Enter 'dwttool help' for help."; | ||
enum invalidAmountError = "ERROR: Invalid amount of arguments given. Enter 'dwttool help' for help."; | ||
enum invalidTypeError = "ERROR: Port must be a number."; | ||
enum missingTemplateError = "ERROR: Could not find template '%s'."; | ||
enum createProjectError = "ERROR: %s already exists. Try another name."; | ||
enum createFileError = "ERROR: Could not create file %s from template %s."; | ||
enum readFileError = "ERROR: Could not read file %s."; | ||
enum readTemplateError = "ERROR: Could not read template %s."; | ||
} | ||
|
||
// Do not indent! | ||
private enum exampleTemplate = " | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<!-- #BeginEditable \"head\" --> | ||
<!-- #EndEditable --> | ||
</head> | ||
<body> | ||
<!-- #BeginEditable \"content\" --> | ||
<!-- #EndEditable --> | ||
</body> | ||
</html>"; | ||
|
||
private void main(string[] args) | ||
{ | ||
// CLI handling | ||
try | ||
{ | ||
switch (args[1]) | ||
{ | ||
case "create": | ||
switch (args[2]) | ||
{ | ||
case "page": | ||
if (args.length == 5) | ||
{ | ||
createPage(args[3], args[4]); | ||
break; | ||
} | ||
else | ||
{ | ||
writeln(invalidAmountError); | ||
break; | ||
} | ||
case "project": | ||
if (args.length == 4) | ||
{ | ||
createProject(args[3]); | ||
break; | ||
} | ||
else | ||
{ | ||
writeln(invalidAmountError); | ||
break; | ||
} | ||
default: writeln(invalidArgumentError); | ||
} | ||
break; | ||
case "update": | ||
switch (args[2]) | ||
{ | ||
case "page": | ||
if (args.length == 5) | ||
{ | ||
updatePage(args[3], args[4]); | ||
break; | ||
} | ||
else | ||
{ | ||
writeln(invalidAmountError); | ||
break; | ||
} | ||
case "project": | ||
if (args.length == 4) | ||
{ | ||
updateProject(args[3]); | ||
break; | ||
} | ||
else | ||
{ | ||
writeln(invalidAmountError); | ||
break; | ||
} | ||
default: writeln(invalidArgumentError); | ||
} | ||
break; | ||
case "serve": | ||
if (args.length == 2) | ||
{ | ||
serveProject; | ||
break; | ||
} | ||
else | ||
{ | ||
writeln(invalidAmountError); | ||
break; | ||
} | ||
case "help": | ||
if (args.length == 2) | ||
{ | ||
showHelp; | ||
break; | ||
} | ||
else | ||
{ | ||
writeln(invalidAmountError); | ||
break; | ||
} | ||
default: writeln(invalidArgumentError); | ||
} | ||
} | ||
catch (RangeError e) | ||
{ | ||
writeln(invalidArgumentError); | ||
} | ||
} | ||
|
||
private void createProject(string projectName) | ||
{ | ||
writeln("Creating new project..."); | ||
|
||
if (!projectName.exists) | ||
{ | ||
mkdir(projectName); | ||
// Create an example template inside of the new project folder | ||
string templatePath = buildPath(projectName, "master.dwt"); | ||
std.file.write(templatePath, exampleTemplate); | ||
} | ||
else | ||
{ | ||
writeln(format(createProjectError, projectName)); | ||
exitDwttool; | ||
} | ||
} | ||
|
||
private void updateProject(string templateName) | ||
{ | ||
writeln("Updating project..."); | ||
|
||
if (templateName.exists) | ||
{ | ||
foreach (DirEntry entry; dirEntries(".", SpanMode.breadth)) | ||
{ | ||
if (endsWith(entry.name, ".html") && entry.isFile) | ||
{ | ||
updatePage(entry.name, templateName); | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
writeln(format(missingTemplateError, templateName)); | ||
exitDwttool; | ||
} | ||
} | ||
|
||
private void createPage(string fileName, string templateName) | ||
{ | ||
writeln("Creating new page..."); | ||
|
||
try | ||
{ | ||
// Determine if a directory has to be made | ||
string pathHierarchy = fileName.dropBack(baseName(fileName).length+1); | ||
if (!pathHierarchy.empty && !pathHierarchy.exists) | ||
{ | ||
mkdirRecurse(pathHierarchy); | ||
} | ||
// A new HTML file is just a copy of a template | ||
copy(templateName, fileName); | ||
} | ||
catch (FileException ex) | ||
{ | ||
writeln(format(createFileError, fileName, templateName)); | ||
} | ||
} | ||
|
||
private void updatePage(string fileName, string templateName) | ||
{ | ||
writeln("Updating page..."); | ||
|
||
string fromFile; | ||
try | ||
{ | ||
fromFile = readText(fileName); | ||
} | ||
catch (FileException ex) | ||
{ | ||
writeln(format(readFileError, fileName)); | ||
exitDwttool; | ||
} | ||
string fromTemplate; | ||
try | ||
{ | ||
fromTemplate = readText(templateName); | ||
} | ||
catch (FileException ex) | ||
{ | ||
writeln(format(readTemplateError, templateName)); | ||
exitDwttool; | ||
} | ||
|
||
// Get editable regions from file | ||
auto matchings = matchAll(fromFile, regex(`<!-- #BeginEditable "(.*?)" -->(.*?)<!-- #EndEditable -->`, "s")); | ||
// Insert editable regions into template | ||
foreach (Captures!string c; matchings) | ||
{ | ||
string r = format(`<!-- #BeginEditable "%s" -->(.*?)<!-- #EndEditable -->`, c[1]); | ||
fromTemplate = replaceAll(fromTemplate, regex(r, "s"), c[0]); | ||
} | ||
|
||
std.file.write(fileName, fromTemplate); | ||
} | ||
|
||
private int serveProject() | ||
{ | ||
writeln("Starting server..."); | ||
writeln("Press Ctrl+C to quit."); | ||
auto router = new URLRouter; | ||
router.get("*", serveStaticFiles(".")); | ||
auto settings = new HTTPServerSettings; | ||
settings.port = 50_000; | ||
settings.bindAddresses = ["::1", "127.0.0.1"]; | ||
listenHTTP(settings, router); | ||
return runEventLoop(); | ||
} | ||
|
||
private void showHelp() | ||
{ | ||
writeln(format("dwttool - A tool to manage websites based on Dynamic Web Templates - Version %s", ver)); | ||
writeln(""); | ||
writeln("Usage:"); | ||
writeln(" dwttool create project <project> Create new dwttool project"); | ||
writeln(" dwttool create page <page> <template> Create new dwttool page"); | ||
writeln(" dwttool update project <template> Update dwttool project"); | ||
writeln(" dwttool update page <page> <template> Update dwttool page"); | ||
writeln(" dwttool serve Serve dwttool project on port 50000"); | ||
writeln(" dwttool help Read this text"); | ||
} | ||
|
||
private void exitDwttool() | ||
{ | ||
writeln("Exiting..."); | ||
exit(0); | ||
} |