Friday, 24 October 2014

Writing A Writing Tool - Part Two

Wow - Part One got a few visitors! Thanks for popping by - now on with Part Two.

Seth Ladd from the Dart team dropped a comment on the code - you'll notice all fields are lower case now :-) This was an easy change thanks to Dart Editor's built in refactoring. I have added more fields to the Chapter class and we can now create a chapter based on just the title. Named constructors coming in handy here. Two methods on Novel allow adding of Chapters and they return a reference for adding more details.


class Novel {

  String title;
  String author;
  List chapters;
  Chapter recent;

  Novel(this.title, this.author) {
    chapters = new List();
  }

  Chapter addPlaceholder(Title) {
    var c = new Chapter.minimal(title);
    chapters.add(c);
    recent = c;
    return c;
  }

  Chapter addChapter(Title, Summary, Characters) {
    var c = new Chapter.detailed(Title, Summary, Characters);
    chapters.add(c);
    recent = c;
    return c;
  }
}

class Chapter {
  String title = "TODO";
  String summary = "TODO";
  String characters = "TODO";
  String pacing = "TODO";
  String atmosphere = "TODO";
  String length = "TODO";
  String locations = "TODO";

  Chapter.minimal(this.title);
  Chapter.detailed(this.title, this.summary, this.characters);
}

Of course, our presentation layer needs a little update for all these new fields:

void txtOut(Novel n) {

  print(n.title);
  print(n.author);
  print("");
  print("${n.chapters.length} Chapters");
  print("");
  n.chapters.forEach((c) {
    print("~" * 80);
    print(c.title.toUpperCase());
    print("- " * 40);
    print(c.summary);
    print("");
    print("CHARACTERS : " + c.characters);
    print("LOCATIONS  : " + c.locations);
    print("PACING     : " + c.pacing);
    print("ATMOSPHERE : " + c.atmosphere);
    print("LENGTH     : " + c.length);
    print("");
  });
}

The test novel needs expand to use the new methods and fields.

void main() {

  print("Novel Planner v0.2");
  print("");

  //---

  Novel n = new Novel("Dart Chronicles", "D. Art");
  Chapter cur;

  cur = n.addChapter("On A Boat", "Sailing the sea and meeting the crew.", "Sam the Sailor");
  cur.pacing = "Lazy";
  cur.atmosphere = "Inviting";
  cur.length = "short";
  cur.locations = "The North Sea";

  cur = n.addChapter("On A Plane", "Flying High and introduce ticking bomb plot.", "Petra the Pilot");
  cur.pacing = "Rapid";
  cur.atmosphere = "Tense";
  cur.length = "medium";

  cur = n.addChapter("The Moonbase", "Introduces the new location and Rab the Robot.", "Rab the Robot");
  cur.pacing = "Slow";
  cur.atmosphere = "Sterile";
  cur.length = "long";
  cur.locations = "Earth's Moon";

  cur = n.addPlaceholder("Epilogue");

  //---
  txtOut(n);
}

Grab the code from Github - https://github.com/daftspaniel/dart-nanowrimoplanner

Right, I think that is looking good now. I am going to feed in my current novel plan. Part Three will be based on tweaks from using it for real and suggestions from comments. Dart has been a very productive language to write this in - glad I chose it over Python for this task. Happy coding and novel writing!


Thursday, 23 October 2014

Writing A Writing Tool - Part One

This is first in a series of blog posts where I will blog the creation of a simple writing tool as a Dart command line application. The background to this is NaNoWriMo which challenges anyone in the world to write a 50,000 word novel during November. Luckily you are allowed to plan in advance (there is not last minute revealed theme or requirement). I started with pen and paper which has its benefits but is too static for my liking! In the past I have written presentation materials in Python to escape Powerpoint and don't want to live in a database or spreadsheet for storytelling.

Important : This series will probably not have any challenging code but is a real world problem for me! Sorry to bore the experts :-)

Okay to get started we will need a basic data structure.

class Novel
{
  String Title;
  String Author;
  List Chapters;

  Novel(this.Title, this.Author){
    Chapters = new List();
  }

  void addChapter(Title, Summary, Characters ){  
    Chapters.add(new Chapter(Title, Summary, Characters));
  }
}

class Chapter
{
  String Title = "TODO";
  String Summary = "TODO";
  String Characters = "TODO";

  Chapter(this.Title,
          this.Summary,
          this.Characters){}
}

We can output using print - maybe HTML later.

void txtOut(Novel n)
{
  n.Chapters.forEach( (c) {
    print("~" * 80);
    print(c.Title.toUpperCase());
    print("- " * 40);
    print(c.Summary);
    print("");
    print("CHARACTERS : " + c.Characters);
    print("");
  } );
}

Finally we can create a 2 chapter novel very easily!

void main() {

  print("Novel Planner v0.1");
  print("");
  
  //---

  Novel n = new Novel("Dart Chronicles", "D. Art");

  n.addChapter("On A Boat", "Sailing the sea and meeting the crew.", "Sam the Sailor");
  n.addChapter("On A Plane", "Flying High and introduce ticking bomb plot.", "Petra the Pilot");

  //---
  txtOut(n);
}

Our novel plan so far:

Novel Planner v0.1

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ON A BOAT
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Sailing the sea and meeting the crew.

CHARACTERS : Sam the Sailor

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ON A PLANE
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Flying High and introduce ticking bomb plot.

CHARACTERS : Petra the Pilot


I did say this is very simple so I hope Dart newbies can chip in! All code will be kept on GitHub. I welcome patches.

Grab the code from Github - https://github.com/daftspaniel/dart-nanowrimoplanner

Next iteration will add more fields for a chapter and improve the output. Already I like it - I can fiddle with details and the order but still get a neat output each time.