GTD Style Wikiの日記を複数表示可能にした

自分用メモに、GTD Style Wikiを使っています。ネットにつながなくても使えるので、シチュエーションによっては便利だと思います。
さて、GTD Style Wikiの日記機能を強化の記事に、コメントをいただきました。

1日に数件新規日記を作成すると、もちろん新しい記事は作成されるのですが、全てが1行で表示されてしまいます。
これを項目ごとに改行するにはGtdCalendarMacroのどこを触ればよいでしょうか。

原因を探ってみたところ、特定できました。
GtdCalendarMacroの480行目を

旧) if (i + 1 < list.length)
新) if (i + 1 < diaryList.length)

とすると、所望の動作になると思います。ちょっとミスしちゃいました。ごめんなさい。

一応、以降に、全文を記載しておきますね。

/***

!!Version
1.1b

!!Description
カレンダーを表示する.

!!Usage
{{{<<gtdCalendar offset open size>>}}}

|!offset|表示月のオフセット-1:先月、0:今月、1:来月 ...|
|!open|"open"を指定すると当日分のスケジュールが開いた状態で表示される|
|!size|フォントサイズ|

!!Configuration
開始曜日(0:Sun, 1:Mon, 2:Tue ...) <<option txtGtdCalendarStartDay>>

***/

//{{{
if (config.options.txtGtdCalendarStartDay == undefined)
  config.options.txtGtdCalendarStartDay = 0;

config.macros.gtdCalendar = {
  scheduledDate: null,
  diaryDate: null,
  holidays: null
};

config.macros.gtdCalendar.handler = function(place,macroName,params)
{
  var m = config.macros.gtdCalendar;

  refreshStyles("gtdStyleSheet");

  var wrapper = createTiddlyElement(place,"div",null,"calendar",null);

  if (!m.holidays)
    m.holidays = m.getHolidays();

  wrapper.name = "gtdCalendar";
  wrapper.setAttribute("monthOffset", "0");
  wrapper.setAttribute("yearOffset", "0");

  if (params[0]) wrapper.setAttribute("monthOffset", params[0]);
  if (params[2]) wrapper.style.fontSize = params[2];

  m.show(wrapper);
  if (params[1] == "open") {
    var now = new Date();
    m.openContent(wrapper, now.formatString("YYYY0MM0DD"));
  }
}

// document.getElementsByName()では動的に作られたノードが
// 取得できないバグ(IE、Opera)対策
config.macros.gtdCalendar.getElementsByName = function(place, tag, name)
{
  var list = new Array();
  var tmplist = place.getElementsByTagName(tag);
  for (var i=0; i<tmplist.length; i++)
    if (tmplist[i].name == name)
      list.push(tmplist[i]);
  return list;
}

config.macros.gtdCalendar.refresh = function(hint) {

  var m = config.macros.gtdCalendar;
  var cnt = 0;
  var cal = m.getElementsByName(document, "div", "gtdCalendar");
  for (var i = 0; i < cal.length; i++) {
    var links = cal[i].getElementsByTagName("a");
    for (var j = 0; j < hint.length; j++) {
      for (var k = 0; k < links.length; k++) {
	var param = links[k].getAttribute("param");
	if (param == hint[j]) {
	  var td = links[k].parentNode;

	  if (m.diaryDate[hint[j]] == undefined
	      ||  m.diaryDate[hint[j]] == 0)
	    td.className = td.className.replace(/calendarDiary/, "calendarNoDiary");
	  else
	    td.className = td.className.replace(/calendarNoDiary/, "calendarDiary");

	  if (m.scheduledDate[hint[j]] == undefined
	      ||  m.scheduledDate[hint[j]] == 0)
	    td.className = td.className.replace(/calendarExist/, "calendarEmpty");
	  else
	    td.className = td.className.replace(/calendarEmpty/, "calendarExist");

	  break;
	}
      }
    }

    var content = cal[i].lastChild;
    if (content.className=="calendarContents") {
      var datestr = content.getAttribute("date");
      var now = new Date();
      if (datestr == now.formatString("YYYY0MM0DD")) {
	m.closeContent(cal[i]);
	m.openContent(cal[i], datestr);
      } else {
	for (var j = 0; j < hint.length; j++) {
	  if (datestr == hint[j]) {
	    m.closeContent(cal[i]);
	    m.openContent(cal[i], datestr);
	    break;
	  }
	}
      }
    }
  }
}

config.macros.gtdCalendar.show = function(place) {

  var m = config.macros.gtdCalendar;
  if (!m.scheduledDate)
    m.scheduledDate = m.getScheduledDate();
  if (!m.diaryDate)
    m.diaryDate = m.getDiaryDate();

  var theDay = new Date();
  theDay.setDate(1);
  theDay.setFullYear(theDay.getFullYear() + Number(place.getAttribute("yearOffset")));
  theDay.setMonth(theDay.getMonth() + Number(place.getAttribute("monthOffset")));

  removeChildren(place);

  var tbl = createTiddlyElement(place, 'table');
  var tbody = createTiddlyElement(tbl, 'tbody');

  var tr = createTiddlyElement(tbody, 'tr');

  // ヘッダ表示
  var cssClass = 'calendarHeader';
  var e;
  var td;
  td = createTiddlyElement(tr, 'td', null, cssClass);
  e = createTiddlyButton(td, "<<", "last year", this.onClick);
  e.setAttribute("param", "LastYear");
  td = createTiddlyElement(tr, 'td', null, cssClass);
  e = createTiddlyButton(td, "<", "last month", this.onClick);
  e.setAttribute("param", "LastMonth");

  var thisMonth = theDay.formatString(m.headerFormat);
  var theClass;

  if (m.diaryDate[theDay.formatString("YYYY0MM00")])
    theClass = cssClass + ' calendarDiary';
  else
    theClass = cssClass + ' calendarNoDiary';
  
  if (m.scheduledDate[theDay.formatString("YYYY0MM00")])
    theClass = cssClass + ' calendarExist';
  else
    theClass = cssClass + ' calendarEmpty';
  theClass = theClass + ' calendarClose';
  td = createTiddlyElement(tr, 'td', null, theClass);
  td.setAttribute("colSpan", 3);
  e = createTiddlyButton(td, thisMonth, thisMonth, this.onClick);
  e.setAttribute("param", theDay.formatString("YYYY0MM00"));

  td = createTiddlyElement(tr, 'td', null, cssClass);
  e = createTiddlyButton(td, ">", "next month", this.onClick);
  e.setAttribute("param", "NextMonth");
  td = createTiddlyElement(tr, 'td', null, cssClass);
  e = createTiddlyButton(td, ">>", "next year", this.onClick);
  e.setAttribute("param", "NextYear");


  // 曜日表示
  tr = createTiddlyElement(tbody, 'tr');
  for (var pos = 0; pos < 7; pos++) {
    var e = createTiddlyElement(tr, 'td', null, 'calendarDays', m.days[m.pos2day(pos)]);
  }
  tr = createTiddlyElement(tbody, 'tr');

  // 1日〜末日表示
  var now = (new Date()).formatString("YYYY0MM0DD");
  theDay.setDate(1 - m.day2pos(theDay.getDay()));	// 1日の週の開始曜日に設定
  var nextDay = new Date(theDay);
  var monthCnt = 0;
  if (theDay.getDate() == 1)	// 1日が日曜日の場合足かけ2ヶ月分(それ以外はあしかけ3ヶ月分)
    monthCnt = 1;
  var youbi = m.pos2day(0);
  for (;;) {
    var datestr = theDay.formatString("YYYY0MM0DD");
    var mmdd = datestr.substr(4);
    var cssClass = 'calendarClose';
    if (youbi == 0 || youbi == 6 || m.holidays[datestr] || m.holidays[mmdd])
      cssClass = cssClass + ' calendarHoliday';
    else
      cssClass = cssClass + ' calendarWeekday';
    if (monthCnt == 1)
      cssClass = cssClass + ' calendarThisMonth';
    else
      cssClass = cssClass + ' calendarOtherMonth';
    if (datestr == now)
      cssClass = cssClass + ' calendarToday';

    if (m.diaryDate[datestr])
      cssClass = cssClass + ' calendarDiary';
    else
      cssClass = cssClass + ' calendarNoDiary';

    if (m.scheduledDate[datestr])
      cssClass = cssClass + ' calendarExist';
    else
      cssClass = cssClass + ' calendarEmpty';

    var td = createTiddlyElement(tr, 'td', null, cssClass);
    var tooltip = theDay.getDate();
    if (m.holidays[datestr] && m.holidays[datestr] != true)
      tooltip = tooltip + ' ' + m.holidays[datestr];
    else if (m.holidays[mmdd] && m.holidays[mmdd] != true)
      tooltip = tooltip + ' ' + m.holidays[mmdd];
    var e = createTiddlyButton(td, theDay.getDate(), tooltip, this.onClick);
    e.setAttribute("param", datestr);

    nextDay.setDate(theDay.getDate() + 1)
    youbi = nextDay.getDay();
    if (theDay.getMonth() != nextDay.getMonth())
      monthCnt++;
    if (monthCnt == 1 && m.day2pos(youbi) == 0)
      tr = createTiddlyElement(tbody, 'tr');
    if (monthCnt >= 2 && m.day2pos(youbi) == 0)
      break;
    theDay.setTime(nextDay.getTime());
  }
}

config.macros.gtdCalendar.onClick = function(e)
{
  var m = config.macros.gtdCalendar;

  var calendar;
  for (calendar = this.parentNode;
       calendar.className != 'calendar';
       calendar = calendar.parentNode)
    if (! calendar)
      return false;

  var param = this.getAttribute("param");
  if (param.match(/^[0-9]{8}$/)) {
    m.openContent(calendar, param);

  } else if (param == "LastMonth") {
    var month = Number(calendar.getAttribute("monthOffset"))
    month -= 1;
    calendar.setAttribute("monthOffset", String(month));
    m.show(calendar);
  } else if (param == "NextMonth") {
    var month = Number(calendar.getAttribute("monthOffset"))
    month += 1;
    calendar.setAttribute("monthOffset", String(month));
    m.show(calendar);
  } else if (param == "LastYear") {
    var year = Number(calendar.getAttribute("yearOffset"))
    year -= 1;
    calendar.setAttribute("yearOffset", String(year));
    m.show(calendar);
  } else if (param == "NextYear") {
    var year = Number(calendar.getAttribute("yearOffset"))
    year += 1;
    calendar.setAttribute("yearOffset", String(year));
    m.show(calendar);
  }

  return false;
}


config.macros.gtdCalendar.openContent = function(wrapper, datestr)
{
  var old = config.macros.gtdCalendar.closeContent(wrapper);
  if (datestr == old)
    return;

  var dates = wrapper.getElementsByTagName("td");
  for (var i = 0; i<dates.length; i++) {
    if (!dates[i].firstChild.tagName)
      continue;
    var p = dates[i].firstChild.getAttribute("param");
    if (p && p == datestr) {
      dates[i].className = dates[i].className.replace(/calendarClose/, "calendarOpen");
      break;
    }
  }

  var calendarContent = createTiddlyElement(null,"div",null,"calendarContents",null);
  wrapper.insertBefore(calendarContent, null);
  var text = config.macros.gtdCalendar.getDateItem(datestr);
  calendarContent.setAttribute("date", datestr);
  wikify(text,calendarContent,null,null);
}

config.macros.gtdCalendar.closeContent = function(wrapper)
{
  var datestr = null;

  var content = wrapper.lastChild;
  if (content.className=="calendarContents") {
    datestr = content.getAttribute("date");
    wrapper.removeChild(wrapper.lastChild);

    var dates = wrapper.getElementsByTagName("td");
    for (var i = 0; i<dates.length; i++) {
      if (!dates[i].firstChild.tagName)
	continue;
      var p = dates[i].firstChild.getAttribute("param");
      if (p && p == datestr) {
	dates[i].className = dates[i].className.replace(/calendarOpen/, "calendarClose");
	break;
      }
    }
  }

  return datestr;
}


config.macros.gtdCalendar.getScheduledDate = function()
{
  var list = new Array();
  store.forEachTiddler(function(title,tiddler) {
    if (tiddler.tags.find("todo") != null) {
      for(var t=0; t<tiddler.tags.length; t++) {
	var yyyymmdd = tiddler.tags[t];
	if(yyyymmdd.match(/^[0-9]{8}$/)) {
	  if (list[yyyymmdd] == undefined)
	    list[yyyymmdd] = 0;
	  list[yyyymmdd]++;
	  var yyyymm00 = yyyymmdd.substr(0,6) + "00";
	  if (list[yyyymm00] == undefined)
	    list[yyyymm00] = 0;
	  list[yyyymm00]++;
	  break;
	}
      }
    }
  });
  return list;
}

config.macros.gtdCalendar.getDiaryDate = function()
{
  var list = new Array();
  store.forEachTiddler(function(title,tiddler) {
    if (tiddler.tags.find("Diary") != null) {
      dtitle = tiddler.title;
      // 'YYYY年0MM月0DD日(DDD)'
      var reg    = /^([0-9]{4})年([0-9]{2})月([0-9]{2})日/;
      //var reg    = /^([0-9]{4}).+([0-9]{2}).+([0-9]{2})/;
      var result = dtitle.match(reg);
      if (result != null) {
        var tmp = result[1] + result[2] + result[3];
	var yyyymmdd = tmp.substr(0,8);
	if (list[yyyymmdd] == undefined)
	  list[yyyymmdd] = 0;
	list[yyyymmdd]++;
	var yyyymm00 = yyyymmdd.substr(0,6) + "00";
	if (list[yyyymm00] == undefined)
	  list[yyyymm00] = 0;
	list[yyyymm00]++;
      }
    }
  });
  return list;
}

config.macros.gtdCalendar.getDateItem = function(datestr, min) {

  var m = config.macros.gtdCalendar;

  var regex;
  var list = [];
  var overList = [];
  var diaryList = [];

  var now = new Date();
  var nowstr = now.formatString("YYYY0MM0DD");
  var nownum = Number(nowstr);

  // Diaryのアイテムで該当日時datestrのものを探索 > diaryList
  store.forEachTiddler(function(title,tiddler) {
    if (tiddler.tags.find("Diary") == null)
      return;
    dtitle = tiddler.title;
    // 'YYYY年0MM月0DD日(DDD)'
    var reg    = /^([0-9]{4})年([0-9]{2})月([0-9]{2})日/;
    var result = dtitle.match(reg);
    if (result != null) {
      var tmp = result[1] + result[2] + result[3];
      var yyyymmdd = tmp.substr(0,8);
      if (yyyymmdd == datestr) {
	var text = tiddlerDate + ' [[' + tiddler.title + ']]';
        diaryList.push(text);
      }
    }
  });

  // ToDoアイテムの探索
  if (datestr == nowstr) {
    regex = '^[0-9]{8}$';
    store.forEachTiddler(function(title,tiddler) {
      if (tiddler.tags.find("todo") == null)
	return;
      for(var t=0; t<tiddler.tags.length; t++)
	if(tiddler.tags[t].match(regex)) {
	  var tiddlerDate = tiddler.tags[t];
	  if (Number(tiddlerDate) > nownum)
	    return;
	  var text = tiddlerDate + ' [[' + tiddler.title + ']]';
	  if (tiddlerDate == nowstr)
	    list.push(text);
	  else
	    overList.push(text);
	  break;
	}
    });
  } else {
    var day = datestr.substr(6);
    if (day == '00')
      regex = '^' + datestr.substr(0,6) + '[0-9]{2}$';
    else
      regex = '^' + datestr + '$';
    store.forEachTiddler(function(title,tiddler) {
      if (tiddler.tags.find("todo") == null)
	return;
      for(var t=0; t<tiddler.tags.length; t++)
	if(tiddler.tags[t].match(regex)) {
	  var tiddlerDate = tiddler.tags[t];
	  var text = tiddlerDate + ' [[' + tiddler.title + ']]';
	  list.push(text);
	  break;
	}
    });
  }

  list.sort();
  var content = "";
  if (datestr.substr(6) != '00')
    content = '<<gtdNewTiddler todo ' + datestr + '>><<br>><<br>>';
  for (var i = 0; i < list.length; i++) {
    var tiddlerDate = list[i].substr(0,8);
    var dt = newDateYYYYMMDD(tiddlerDate);
    if (Number(tiddlerDate) < nownum)
      content = content + '@@color:red;' + dt.formatString(m.listDateFormat) + '@@ ';
    else if (tiddlerDate == nowstr)
      content = content + "''" + dt.formatString(m.listDateFormat) + "'' ";
    else
      content = content + dt.formatString(m.listDateFormat) + ' ';
    content = content + list[i].substr(8);
    if (i + 1 < list.length)
      content = content + "<<br>>";
  }

  if (overList.length > 0) {
    content = content + "\n----\n";
    overList.sort();
    for (var i = 0; i < overList.length; i++) {
      var dt = newDateYYYYMMDD(overList[i].substr(0,8));
      content = content + '@@color:red;' + dt.formatString(m.listMonthDateFormat) + '@@ '
	+ overList[i].substr(8);
      if (i + 1 < overList.length)
	content = content + "<<br>>";
    }
  }

  // Diaryアイテムの表示
  if (diaryList.length > 0) {
    content = content + "\n<----->\n";
    diaryList.sort();
    for (var i = 0; i < diaryList.length; i++) {
      content = content + "''日記'' " + diaryList[i].substr(10);
      if (i + 1 < diaryList.length)
        content = content + "<<br>>";
    }
  }

  var cnt = list.length + overList.length + diaryList.length;
  if (cnt > 0)
    cnt--;
  if (datestr.substr(6) != '00')
    cnt += 2;
  for (var t = 0; t < min - cnt; t++)
    content = content + '<<br>>';
  return content;
}


config.macros.gtdCalendar.getHolidays = function()
{
  var list = new Array();
  var text = store.getTiddlerText("Holiday");
  if (text) {
    var lines = text.split("\n");
    for (i = 0; i<lines.length; i++) {
      if (lines[i].match(/^([0-9]+)\s+(\S+)/))
	list[RegExp.$1] = RegExp.$2;
      else if (lines[i].match(/^([0-9]+)/))
	list[RegExp.$1] = true;
    }
  }

  return list;
}

config.macros.gtdCalendar.day2pos = function(day)
{
  var start = Number(config.options.txtGtdCalendarStartDay);
  var pos = day - start;
  if (pos < 0)
    pos += 7;
  return pos;
}

config.macros.gtdCalendar.pos2day = function(pos)
{
  var start = Number(config.options.txtGtdCalendarStartDay);
  var day = start + pos;
  if (day > 6)
    day -= 7;
  return day;
}

//}}}