Compare commits

...

17 Commits

Author SHA1 Message Date
6a18330768 Add Dockerfiles
Signed-off-by: Jacob Kiers <code@kiers.eu>
2025-05-29 17:06:50 +02:00
Soren Bjornstad
b8187ce0e8
Update README to not call M2 my Zettelkasten 2024-07-29 11:09:29 -05:00
Soren I. Bjornstad
5dad082499 update sphinx version 2024-07-25 16:31:32 -05:00
Soren I. Bjornstad
dad1215958 bump version 2024-07-25 16:25:06 -05:00
Soren I. Bjornstad
abc41c5a3c update TiddlyWiki tiddlers 2024-07-25 16:24:16 -05:00
Soren I. Bjornstad
81c46cc5e4 improve assertion error message 2024-07-25 15:42:11 -05:00
Soren I. Bjornstad
b15c04bdaa add option for custom private person build handling 2024-05-24 07:58:05 -05:00
Soren I. Bjornstad
1dc08cfa34 utility function to split a tiddler list
Implemented by ChatGPT; passed the doctests which I wrote myself and
looks correct.
2024-05-24 07:56:56 -05:00
Soren I. Bjornstad
20c4d09b7d add option to set the saver / root tiddler on 'tzk listen' 2024-05-24 07:56:26 -05:00
Soren I. Bjornstad
295f61299a update sphinx version 2023-10-15 22:11:12 -05:00
Soren I. Bjornstad
18564356c3 add RTD requirements.txt 2023-10-15 22:06:31 -05:00
Soren I. Bjornstad
02786a1fb1 fix type error in sphinx config 2023-10-15 22:03:02 -05:00
Soren I. Bjornstad
d5445f7a1a add RTD config file (now required) 2023-10-15 22:01:18 -05:00
Soren I. Bjornstad
77d95a5ef8 bump version 2023-10-15 21:56:14 -05:00
Soren I. Bjornstad
9b0b5a1824 fix 'npm bin' bug and update to latest ZK 2023-10-15 21:55:26 -05:00
Soren I. Bjornstad
553c175eb5 remove uses of "npm bin"
This was removed from recent Node versions. Using 'npx' is the new way
and should resolve this issue.

I suppose we might run into someone who had a non-working npx and it
breaks, but we'll cross that bridge when we come to it; it works in my
testing and there are people broken in the current version.
2023-10-15 21:27:22 -05:00
Soren I. Bjornstad
650b21a03d fix docs copyright date 2022-08-19 17:36:01 -05:00
1277 changed files with 11429 additions and 3550 deletions

35
.readthedocs.yaml Normal file
View File

@ -0,0 +1,35 @@
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# You can also specify other tool versions:
# nodejs: "20"
# rust: "1.70"
# golang: "1.20"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: cli_docs/conf.py
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
# builder: "dirhtml"
# Fail on all warnings to avoid broken references
# fail_on_warning: true
# Optionally build your docs in additional formats such as PDF and ePub
# formats:
# - pdf
# - epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: cli_docs/requirements.txt

25
Dockerfile Normal file
View File

@ -0,0 +1,25 @@
FROM node:alpine
LABEL maintainer="Jacob Kiers <code@kiers.eu>"
ARG USER="User Name"
ARG EMAIL="user.name@example.org"
EXPOSE 8080
VOLUME /app
WORKDIR /app
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["tzk", "listen"]
RUN apk add --no-cache tini py3-pip git
RUN git config --global user.name "${USER}" && \
git config --global user.email "${EMAIL}"
RUN mkdir -p /code/tzk && \
wget https://code.kiers.eu/jjkiers/tzk/archive/jk-version.tar.gz -O - \
| tar --strip-components 1 -xzC /code/tzk
RUN pip install --break-system-packages /code/tzk
RUN npx tiddlywiki

23
Dockerfile.localbuild Normal file
View File

@ -0,0 +1,23 @@
FROM node:alpine
LABEL maintainer="Jacob Kiers <code@kiers.eu>"
ARG USER="User Name"
ARG EMAIL="user.name@example.org"
EXPOSE 8080
VOLUME /app
WORKDIR /app
COPY . /code/tzk
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["tzk", "listen"]
RUN apk add --no-cache tini py3-pip git
RUN git config --global user.name "${USER}" && \
git config --global user.email "${EMAIL}"
RUN pip install --break-system-packages /code/tzk
RUN npx tiddlywiki

View File

@ -5,12 +5,12 @@
for maintaining personal notes
in something approaching the Zettelkasten method.
Its updated periodically from whatever tooling Im currently using
[in my own Zettelkasten](https://zettelkasten.sorenbjornstad.com).
[in my own thinking workspace](https://mosmu.se).
As such, its currently considered alpha-quality;
while it ought to be very stable and theres no meaningful risk of data loss,
updating to a newer version might be difficult
and Im unlikely to accept patches
unless theyre something I want in my own Zettelkasten.
unless theyre something I want for myself.
This is intended primarily as a nice starting platform
on which to build your own tooling.

View File

@ -6,28 +6,25 @@
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# Instead of adding things manually to the path, we just ensure we install esc
# in editable mode in our environment.
import datetime
# -- Project information -----------------------------------------------------
project = 'tzk'
copyright = '2021 Soren Bjornstad'
copyright = str(datetime.date.today().year) + ' Soren Bjornstad'
author = 'Soren Bjornstad'
# The short X.Y version
version = "0.3.0"
version = "0.5.0"
# The full version, including alpha/beta/rc tags
release = "0.3.0"
release = "0.5.0"
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
needs_sphinx = '1.8.5'
needs_sphinx = '5.0.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@ -52,13 +49,6 @@ source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.

View File

@ -0,0 +1,4 @@
# docs
sphinx>=5.0.0 # newer versions display function names in the wrong color?
sphinx_rtd_theme==0.5.2
Jinja2<3.1 # https://github.com/readthedocs/readthedocs.org/issues/9038

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
-e .
# docs
sphinx==3.5.4 # newer versions display function names in the wrong color?
sphinx==4.2.0 # newer versions display function names in the wrong color?
sphinx_rtd_theme==0.5.2
Jinja2<3.1 # https://github.com/readthedocs/readthedocs.org/issues/9038

View File

@ -9,7 +9,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="tzk",
version="0.3.0",
version="0.5.0",
author="Soren I. Bjornstad",
author_email="zettelkasten@sorenbjornstad.com",
description="Build tool for TiddlyWiki Zettelkasten",

View File

@ -91,6 +91,12 @@ class ListenCommand(CliCommand):
help="Host to listen on.",
default=str(cm().listen_host or "127.0.0.1"),
)
parser.add_argument(
"--root-tiddler",
metavar="TIDDLER",
help="Saver tiddler to use (for LazyLoading).",
default=str(cm().listen_root_tiddler or "$:/core/save/all"),
)
parser.add_argument(
"-p", "--port",
metavar="PORT",
@ -120,7 +126,8 @@ class ListenCommand(CliCommand):
f"host={args.host}",
f"port={args.port}",
f"username={args.username}",
f"password={args.password}")
f"password={args.password}",
f"root-tiddler={args.root_tiddler}")
]
)
except KeyboardInterrupt:

View File

@ -11,7 +11,6 @@ information about the defined products without actually running any build steps.
"""
from collections.abc import Mapping
from contextlib import contextmanager
import functools
import itertools
import os
@ -20,7 +19,7 @@ import re
import shutil
import subprocess
import tempfile
from typing import Callable, Dict, Generator, List, Optional, Set, Sequence, Tuple
from typing import Callable, Dict, Generator, List, Optional, Set, Sequence, Tuple, Union
from tzk import git
from tzk import tw
@ -171,7 +170,7 @@ def _find_kill_phrases(phrases: Set[str]):
for regex in regexes:
if re.search(regex, line):
failures.append((regex, str(tid_file), line))
return failures
@ -322,14 +321,16 @@ def compile_html_file(
def _private_people_replacement_table(
initialer: Callable[[str], str] = None) -> Dict[str, str]:
initialer: Callable[[str], str] = None,
is_public: Callable[[str], Union[bool, None]] = None,
) -> Dict[str, str]:
"Build table of private people and their transformed initials."
def _initials_from_tiddler_name(name: str) -> str:
m = re.match(r"^(?:Mr|Ms|Mx|The)(?P<camel_case_name>.*?)\.tid", name)
assert m
return '.'.join(i for i in m.group('camel_case_name') if i.isupper()) + '.'
if initialer is None:
initialer = _initials_from_tiddler_name
@ -337,6 +338,20 @@ def _private_people_replacement_table(
person_tiddlers = (i for i in tiddlers if re.match("^(Mr|Ms|Mx|The)", i.name))
private_person_tiddlers = []
for pt in person_tiddlers:
# If the is_public handler is defined, call it. If not defined
# or it returns None for this line, proceed to the default
# handler.
if is_public:
delegated_publicity_status = is_public(pt)
if delegated_publicity_status is True:
continue
elif delegated_publicity_status is False:
private_person_tiddlers.append(pt)
continue
assert delegated_publicity_status is None, \
f"publicity status was {delegated_publicity_status}"
# Default handler.
with pt.open() as f:
for line in f:
if line.startswith("tags:"):
@ -500,8 +515,8 @@ def _privatize_line(line: str, replacement_table: Dict[str, str],
new_line = line[0:start_idx] + 'PrivatePerson' + line[end_idx:]
else:
link = line[start_idx:end_idx]
raise ValueError("Unknown type of link '{link}'.")
raise ValueError(f"Unknown type of link '{link}'.")
if new_line:
line = new_line
dirty = True
@ -510,7 +525,7 @@ def _privatize_line(line: str, replacement_table: Dict[str, str],
increment_iterator_by = len(new_line) - len(line)
except StopIteration:
pass
if dirty:
return line
else:
@ -518,7 +533,10 @@ def _privatize_line(line: str, replacement_table: Dict[str, str],
@tzk_builder
def replace_private_people(initialer: Callable[[str], str] = None, replace_link_text: bool = False) -> None:
def replace_private_people(
initialer: Callable[[str], str] = None,
replace_link_text: bool = False,
is_public: Callable[[str], Union[bool, None]] = None) -> None:
"""
Replace the names of people who are not marked Public with their initials.
@ -551,16 +569,25 @@ def replace_private_people(initialer: Callable[[str], str] = None, replace_link_
This means that when using this feature, having the
link text also be meaningful after redaction is important.
:param is_public: If you want to define a person tiddler being public/private by
some criteria other than having a 'Public' tag, pass a
callable here. A Path object for the tiddler is the sole argument.
Return True if the tiddler is public / should be included in the
edition, False if it's private, or None to delegate to the default
handler.
.. warning ::
Using this link replacement feature does not redact everything, just the link
(and the link text with `replace_link_text` enabled). So *do not* rely on it
for redacting everything. Making a tiddler public still needs consideration and
tooling is there to help, not to replace your own judgment.
This function redacts only square-bracketed and CamelCase links themselves.
The text of links with different link target and text is NOT redacted unless
``replace_link_text`` is enabled, and names used outside of links
are NEVER redacted. Making a tiddler public still needs consideration and
this function is here to help, not to replace your judgment! Consider adding
kill phrases for anyone you want to be doubly sure is not publicly mentioned.
"""
assert 'public_wiki_folder' in build_state
replacement_table = _private_people_replacement_table(initialer)
root = (Path(build_state['public_wiki_folder']) / "tiddlers")
replacement_table = _private_people_replacement_table(initialer, is_public)
root = Path(build_state['public_wiki_folder']) / "tiddlers"
tid_files = itertools.chain(root.glob("**/*.tid"), root.glob("**/*.json"))
for tiddler in tid_files:

View File

@ -0,0 +1,31 @@
{
"journals":{
"lastDayOfWeek":"0",
"formatter":"$:/macros/bj/Calendar/journalfmt.js",
"titlebold":"no",
"highlightThisDay":"no",
"highlightThisDate":"yes"
},
"default":{
"lastDayOfWeek":"0",
"formatter":"$:/macros/bj/Calendar/journalslinked.js",
"titlebold":"yes",
"highlightThisDay":"no",
"highlightLinks":"yes"
},
"diary":{
"lastDayOfWeek":"0",
"formatter":"$:/macros/bj/Calendar/diary.js",
"titlebold":"yes",
"highlightThisDay":"no",
"highlightLinks":"yes"
},
"plain":{
"lastDayOfWeek":"0",
"formatter":"",
"titlebold":"yes",
"highlightThisDay":"yes",
"highlightThisDate":"no"
}
}

View File

@ -0,0 +1,3 @@
module-type: library
title: $:/config/bj/Calendar.json
type: application/json

View File

@ -0,0 +1,96 @@
/*\
title: $:/core/modules/widgets/macrorefresh.js
type: application/javascript
module-type: widget
Macrocall widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var MacroCallWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
MacroCallWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
MacroCallWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
this.renderChildren(parent,nextSibling);
};
/*
Compute the internal state of the widget
*/
MacroCallWidget.prototype.execute = function() {
var self = this;
// Get the parse type if specified
this.parseType = this.getAttribute("$type","text/vnd.tiddlywiki");
this.renderOutput = this.getAttribute("$output","text/html");
// Merge together the parameters specified in the parse tree with the specified attributes
this.params = this.parseTreeNode.params ? this.parseTreeNode.params.slice(0) : [];
$tw.utils.each(this.attributes,function(attribute,name) {
if(name.charAt(0) !== "$") {
self.params.push({name: name, value: attribute});
}
});
// Get the macro value
var text = this.getVariable(this.parseTreeNode.name || this.getAttribute("$name"),{params: this.params}),
parseTreeNodes;
// Are we rendering to HTML?
if(this.renderOutput === "text/html") {
// If so we'll return the parsed macro
var parser = this.wiki.parseText(this.parseType,text,
{parseAsInline: !this.parseTreeNode.isBlock});
parseTreeNodes = parser ? parser.tree : [];
} else {
// Otherwise, we'll render the text
var plainText = this.wiki.renderText("text/plain",this.parseType,text,{parentWidget: this});
parseTreeNodes = [{type: "text", text: plainText}];
}
// Construct the child widgets
this.makeChildWidgets(parseTreeNodes);
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
MacroCallWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if($tw.utils.count(changedAttributes) > 0) {
// Rerender ourselves
this.refreshSelf();
return true;
}
//else
if (this.getAttribute("$refresh")) {
var params = this.params.slice(0);
params.push({name: "changedTiddlers", value: changedTiddlers});
if (this.getVariable(this.getAttribute("$refresh"),{params: params})) {
// Rerender ourselves
this.refreshSelf();
return true;
}
//else
}
return this.refreshChildren(changedTiddlers);
};
exports.macrorefresh = MacroCallWidget;
})();

View File

@ -0,0 +1,3 @@
module-type: widget
title: $:/core/modules/widgets/macrorefresh.js
type: application/javascript

View File

@ -0,0 +1,37 @@
/*\
title: $:/macros/bj/Calendar/diary.js
type: application/javascript
module-type: global
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
calendar demo
*/
var Calendar=new Date();
var createMonth= function(mnth,year,options){
var month=[];
for (var i=1;i < 1+daysInMonth(mnth,year);i++) month[i] = createDate(i,mnth,year,options);
return month;
}
function createDate(i,mnth,year,options){
var strong='',tiddlerDate,format = $tw.wiki.getTiddlerText("$:/config/NewJournal/Title") || "YYYY MM DD";
var date=(new Date(year, mnth-1, i));
if (options.highlightLinks=="yes") strong ='!';
tiddlerDate = $tw.utils.formatDateString(date,format);
if ($tw.wiki.getTiddler(tiddlerDate))return centre(strong+'[['+i+'|'+tiddlerDate+']]');
return centre('[['+i+'|'+tiddlerDate+']]');
}
function daysInMonth(iMonth, iYear){
return 32 - new Date(iYear, iMonth-1, 32).getDate();
}
function centre (x){ return ' '+x+' ';}
exports.createMonth = createMonth;
})();

View File

@ -0,0 +1,3 @@
module-type: global
title: $:/macros/bj/Calendar/diary.js
type: application/javascript

View File

@ -0,0 +1,37 @@
/*\
title: $:/macros/bj/Calendar/journalfmt.js
type: application/javascript
module-type: global
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
calendar demo
*/
var Calendar=new Date();
var createMonth= function(mnth,year,options){
var month=[];
for (var i=1;i < 1+daysInMonth(mnth,year);i++) month[i] = createDate(i,mnth,year,options);
return month;
}
function createDate(i,mnth,year,options){
var strong='',tiddlerDate;
var date=(new Date(year, mnth, i));
if (date.toDateString()===Calendar.toDateString()&&options.highlightThisDate=="yes") strong ='!';
tiddlerDate=date.getDate()+
' '+$tw.language.getString("Date/Long/Month/" + (date.getMonth()))+' '+date.getFullYear();
if ($tw.wiki.getTiddler(tiddlerDate)!==undefined) strong ='!';
return centre(strong+'[['+i+'|'+tiddlerDate+']]');
}
function daysInMonth(iMonth, iYear){
return 32 - new Date(iYear, iMonth, 32).getDate();
}
function centre (x){ return ' '+x+' ';}
exports.createMonth = createMonth;
})();

View File

@ -0,0 +1,3 @@
module-type: global
title: $:/macros/bj/Calendar/journalfmt.js
type: application/javascript

View File

@ -0,0 +1,37 @@
/*\
title: $:/macros/bj/Calendar/journalslinked.js
type: application/javascript
module-type: global
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
calendar demo
*/
var Calendar=new Date();
var createMonth= function(mnth,year,options){
var month=[];
for (var i=1;i < 1+daysInMonth(mnth,year);i++) month[i] = createDate(i,mnth,year,options);
return month;
}
function createDate(i,mnth,year,options){
var strong='',tiddlerDate,format = $tw.wiki.getTiddlerText("$:/config/NewJournal/Title") || "YYYY MM DD";
var date=(new Date(year, mnth-1, i));
if (options.highlightLinks=="yes") strong ='!';
tiddlerDate = $tw.utils.formatDateString(date,format);
if ($tw.wiki.getTiddler(tiddlerDate))return centre(strong+'[['+i+'|'+tiddlerDate+']]');
return i;
}
function daysInMonth(iMonth, iYear){
return 32 - new Date(iYear, iMonth-1, 32).getDate();
}
function centre (x){ return ' '+x+' ';}
exports.createMonth = createMonth;
})();

View File

@ -0,0 +1,3 @@
module-type: global
title: $:/macros/bj/Calendar/journalslinked.js
type: application/javascript

View File

@ -0,0 +1,140 @@
/*\
title: $:/macros/buggyj/Calendar/base.js
type: application/javascript
module-type: macro
<<diary year month>>
<<diary year>> - year calendar
<<diary>> - this month
Options:$:/macros/diary/options.json
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
CAL demo
*/
exports.name = "calendarbase";
exports.params = [
{ name: "year" },{ name: "month" },{ name: "opts" }
];
/*
Run the macro
*/
exports.run = function(year, month,opts) {
if (!opts) opts="default";
var options = $tw.wiki.getTiddlerData("$:/config/bj/Calendar.json")[opts]||
{lastDayOfWeek:"6",formatter:"",titlebold:"",highlightThisDay:"",highlightThisDate:""};
var createMonth;
try {
createMonth = require(options.formatter).createMonth;
} catch (e) {
createMonth= function(mnth,year){
var month=[];
for (var i=1;i < 1+daysInMonth(mnth,year);i++) month[i] = i;
return month;
}
}
var boldtitle=(options.titlebold=='yes')?'!':'';
var day_of_week = (function () {
var days = [];
for (var i = 0; i < 7; i++) {days[i] = $tw.language.getString("Date/Short/Day/" + i); }
return days;
})();
var month_of_year = (function () {
var months = [];
for (var i = 1; i < 13; i++) {months[i] = $tw.language.getString("Date/Long/Month/" + i); }
return months;
})();
var Calendar = new Date();
var thisyear = Calendar.getFullYear(); // year (xxxx)
var thismonth = Calendar.getMonth()+1; // month (0-11)
var thisday = Calendar.getDay(); // day (0-6)
var WEEKFIN = parseInt(options.lastDayOfWeek);
var MONTHS_IN_YEAR=12;
var lf ='\n';
var cal='<div>'+lf+lf;
var ayear=thisyear;
if (!!month) {
if (!!year) {
cal+=calendar (month,year,options);
} else {
cal+=calendar (month,thisyear,options);
}
} else {
if (!!year) {
cal+=titleOfYear(year);
options.seperateYearHeading = 'yes';
ayear=year;
for(var i=0; i<MONTHS_IN_YEAR; i+=2)
cal+=splicetable(calendar (i+1,ayear,options),calendar (i+2,ayear,options));
}
else {
cal+=calendar (thismonth,thisyear,options);
}
}
return cal+lf+lf+'</div>';
function calendar (mnth,year,options){
var month = createMonth(mnth,year,options);
var blankdays = (firstDayInMonth(mnth,year)+13-WEEKFIN)%7;
return titleOfMonth(mnth,year)+createWeekHeading()+
formatAsMonth(month,blankdays);
}
function titleOfMonth(mth,year) {
if (!!options.seperateYearHeading ) {
return '|>|>|>|'+ centre(boldtitle+ month_of_year[mth]) +'|<|<|<|'+lf;
} else {
return '|>|>|>|'+ centre(boldtitle+ month_of_year[mth] + ' ' + year) +'|<|<|<|'+lf;
}
}
function titleOfYear(year) {
return '|>|>|>|>|>|>|>|'+ centre('!'+year) +'|<|<|<|<|<|<|<|'+lf;
}
function centre (x){ return ' '+x+' ';}
function formatAsMonth(month,blankdays){
var theday,blank=['','|','||','|||','||||','|||||','||||||','|||||||'];
var cal=blank[blankdays];//pad out before first day of month
for(var i=1; i < month.length;i++){//first '0' month element is not used
cal+='|'+month[i];
theday=(i+blankdays-1)%7;
if (theday == 6) cal += '|' + lf;
}
if (theday !== 6) cal += blank[7 - theday] + lf;//pad out rest of week, if needed
return cal ;
}
function createWeekHeading(){
var daystitle=[],weekdays= day_of_week.slice(0);
// highlight today's day of week
if (options.highlightThisDay=='yes')weekdays[thisday] ='!'+weekdays[thisday];
for (var i=0;i < weekdays.length; i++) daystitle[i] =centre(weekdays[(i+1+WEEKFIN)%7]);
return '|'+daystitle.join('|')+'|'+lf;
}
function daysInMonth(iMonth, iYear){
return 32 - new Date(iYear, iMonth-1, 32).getDate();
}
function firstDayInMonth(iMonth, iYear){
return new Date(iYear, iMonth-1, 1).getDay();
}
function splicetable (a,b) {
var i,cal='',taba =a.split('\n'),tabb=b.split('|\n');
var limit=(taba.length<tabb.length)?taba.length:tabb.length;//shortest
for (i=0;i<limit-1;i++) cal+=taba[i]+tabb[i]+'|'+lf;
for (;i < taba.length-1;i++) cal+=taba[i]+"||||||||"+lf;
for (;i < tabb.length-1;i++) cal+="||||||||"+tabb[i]+lf;
return cal;
}
}
})();

View File

@ -0,0 +1,3 @@
module-type: macro
title: $:/macros/buggyj/Calendar/base.js
type: application/javascript

View File

@ -0,0 +1,36 @@
/*\
title: $:/macros/buggyj/Calendar/entry.js
type: application/javascript
module-type: macro
<<calendar year month>>
<<calendar year>> - year calendar
<<calendar>> - this month
Options:$:/macros/diary/options.json
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
CAL demo
*/
exports.name = "calendar";
exports.params = [
{ name: "year" },{ name: "month" },{ name: "opts" }
];
/*
Run the macro
*/
exports.run = function(year, month,opts) {
return '<$macrorefresh $name="calendarbase" year="'+year+'" month="'+month+'" opts="'+opts+'" $refresh="calendarrefresh"/>';
}
})();

View File

@ -0,0 +1,3 @@
module-type: macro
title: $:/macros/buggyj/Calendar/entry.js
type: application/javascript

View File

@ -0,0 +1,39 @@
/*\
title: $:/macros/buggyj/Calendar/entry2.js
type: application/javascript
module-type: macro
<<diary year month>>
<<diary year>> - year calendar
<<diary>> - this month
Options:$:/macros/diary/options.json
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
CAL demo
*/
exports.name = "diary";
exports.params = [
{ name: "year" },{ name: "month" },{ name: "opts" }
];
/*
Run the macro
*/
exports.run = function(year, month,opts) {
var tags = $tw.wiki.getTiddlerText("$:/config/NewJournal/Tags");
if (!opts) opts = "diary";
return '<$ifnew fields="""{"tags":"'+tags+'"}""">' +
'<$macrorefresh $name="calendarbase" year="'+year+'" month="'+month+'" opts="'+opts+'" $refresh="calendarrefresh"/>'+ '</$ifnew>';
}
})();

View File

@ -0,0 +1,3 @@
module-type: macro
title: $:/macros/buggyj/Calendar/entry2.js
type: application/javascript

View File

@ -0,0 +1,87 @@
/*\
title: $:/macros/buggyj/Calendar/ifnew.js
type: application/javascript
module-type: widget
Linkcatcher widget
ToDo - add message param to listen for other mssg and action to set other actions (link just create)
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var IfNewWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
this.addEventListeners([
{type: "tm-navigate", handler: "handleNavigateEvent"}
]);
};
/*
Inherit from the base widget class
*/
IfNewWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
IfNewWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
this.renderChildren(parent,nextSibling);
};
/*
Compute the internal state of the widget
*/
IfNewWidget.prototype.execute = function() {
// Get our parameters
this.fields = this.getAttribute("fields");
this.catchMessage = this.getAttribute("message");
// Construct the child widgets
this.makeChildWidgets();
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
IfNewWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.fields || changedAttributes.message ) {
this.refreshSelf();
return true;
} else {
return this.refreshChildren(changedTiddlers);
}
};
/*
Handle a tm-navigate event
*/
IfNewWidget.prototype.handleNavigateEvent = function(event) {
var tiddler = this.wiki.getTiddler(event.navigateTo),fds;
if(tiddler) return true;
try {
fds=JSON.parse(this.fields);
} catch(e) {
fds={};
}
fds.title = event.navigateTo;
if(this.parentWidget) {
this.parentWidget.dispatchEvent({
type: "tm-new-tiddler",
param: fds
});
}
return false;
};
exports.ifnew = IfNewWidget;
})();

View File

@ -0,0 +1,3 @@
module-type: widget
title: $:/macros/buggyj/Calendar/ifnew.js
type: application/javascript

View File

@ -0,0 +1,105 @@
/*\
title: $:/macros/buggyj/Calendar/refresh.js
type: application/javascript
module-type: macro
<<diary year month>>
<<diary year>> - year calendar
<<diary>> - this month
Options:$:/macros/diary/options.json
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
CAL demo
*/
exports.name = "calendarrefresh";
exports.params = [
{ name: "year" },{ name: "month" },{ name: "opts" },{name:"changedTiddlers"}
];
// Source: http://stackoverflow.com/questions/497790
var dates = {
convert:function(d) {
// Converts the date in d to a date-object. The input can be:
// a date object: returned without modification
// an array : Interpreted as [year,month,day]. NOTE: month is 0-11.
// a number : Interpreted as number of milliseconds
// since 1 Jan 1970 (a timestamp)
// a string : Any format supported by the javascript engine, like
// "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
// an object : Interpreted as an object with year, month and date
// attributes. **NOTE** month is 0-11.
return (
d.constructor === Date ? d :
d.constructor === Array ? new Date(d[0],d[1],d[2]) :
d.constructor === Number ? new Date(d) :
d.constructor === String ? new Date(d) :
typeof d === "object" ? new Date(d.year,d.month,d.date) :
NaN
);
},
compare:function(a,b) {
// Compare two dates (could be of any type supported by the convert
// function above) and returns:
// -1 : if a < b
// 0 : if a = b
// 1 : if a > b
// NaN : if a or b is an illegal date
// NOTE: The code inside isFinite does an assignment (=).
return (
isFinite(a=this.convert(a).valueOf()) &&
isFinite(b=this.convert(b).valueOf()) ?
(a>b)-(a<b) :
NaN
);
},
inRange:function(d,start,end) {
// Checks if date in d is between dates in start and end.
// Returns a boolean or NaN:
// true : if d is between start and end (inclusive)
// false : if d is before start or after end
// NaN : if one or more of the dates is illegal.
// NOTE: The code inside isFinite does an assignment (=).
return (
isFinite(d=this.convert(d).valueOf()) &&
isFinite(start=this.convert(start).valueOf()) &&
isFinite(end=this.convert(end).valueOf()) ?
start <= d && d <= end :
NaN
);
}
}
/*
Run the macro
*/
exports.run = function(year, month,opts,changedTiddlers) {
var found = false;
var journaltag = "Journal";
$tw.utils.each(changedTiddlers,function(attribute,name) {
if (attribute.deleted) {
return;
}
var tiddler = $tw.wiki.getTiddler(name);
var tags = (tiddler.fields.tags || []).slice(0);
if(tags.indexOf(journaltag) != -1) {
found = true;
}
});
if (found) return "found";
return "";
}
})();

View File

@ -0,0 +1,3 @@
module-type: macro
title: $:/macros/buggyj/Calendar/refresh.js
type: application/javascript

View File

@ -0,0 +1,22 @@
title: $:/plugins/bj/Calendar/license
The MIT License (MIT)
Copyright (c) 2014 Jeffrey Wikinson aka buggyj
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.

View File

@ -0,0 +1,4 @@
title: $:/plugins/bj/Calendar/readme
For documentation see the project home at
http://bjtools.tiddlyspot.com#ExtendableCalendar

View File

@ -0,0 +1,13 @@
caption: Calendar
tags: $:/tags/SideBar
title: $:/plugins/bj/calendar/sidbar
type: text/vnd.tiddlywiki
<$reveal state="$:/temp/plugins/bj/Calendar" text="Year" type="nomatch">
<$button set="$:/temp/plugins/bj/Calendar" setTo="Year">Year</$button>
<<calendar "" "">>
</$reveal>
<$reveal state="$:/temp/plugins/bj/Calendar" text="Year" type="match">
<$button set="$:/temp/plugins/bj/Calendar" setTo="Month">Month</$button>
<<calendar 2014 "">>
</$reveal>

View File

@ -0,0 +1,11 @@
{
"author": "JeffreyWilkinson",
"core-version": ">=5.1.11",
"dependents": "",
"description": "calendar with date formatter addons",
"list": "readme license",
"plugin-type": "plugin",
"source": "https://github.com/buggyj/TW5-tools",
"title": "$:/plugins/bj/Calendar",
"version": "1.11.0"
}

View File

@ -9,5 +9,6 @@
"plugin-type": "plugin",
"source": "https://github.com/TheDiveO/TW5FontAwesome",
"title": "$:/plugins/TheDiveO/FontAwesome",
"version": "1.2.18"
"version": "1.2.18",
"dependents": ""
}

View File

@ -8,7 +8,7 @@ type: text/vnd.tiddlywiki
<$set name="tr-rendering" value="yes">
<span id="tr-version">1.3.3</span>
<span id="tr-version">1.3.5</span>
{{||$:/plugins/sobjornstad/TiddlyRemember/templates/AnkiDecks}}
{{||$:/plugins/sobjornstad/TiddlyRemember/templates/AnkiTags}}

View File

@ -2,7 +2,7 @@
"title": "$:/plugins/sobjornstad/TiddlyRemember",
"description": "TiddlyRemember: Embed Anki notes in your TiddlyWiki",
"author": "Soren Bjornstad",
"version": "1.3.3",
"version": "1.3.5",
"core-version": ">=5.1.21",
"source": "https://github.com/sobjornstad/TiddlyRemember",
"list": "readme license",

Some files were not shown because too many files have changed in this diff Show More