Splitting a title

So…I want to take an existing title, split it and then use it to create a new tiddler.
It works in that the button calls the macro but it’s not grabbing the vars un and an.
HEEEELP ME PLEEEAAASSEEEE

Ste

\define Set_New_Tiddler()
<$vars  un={{{ [{{!!title}}split[]first[7]last[2]join[]]  }}}>
<$vars  an={{{ [{{!!title}}split[]first[14]last[1]join[]]  }}}>
{{{ [[Some text]addsuffix<un>[some text]addsuffix<an>] }}}
\end

and a button:

<$button>
Create Tiddler
<$vars Title={{!!Title}}>
<$wikify name="newname" text=<<Set_New_Tiddler>>>
<$action-setfield $tiddler=<<newname>> tags='Deadline Schedule' />
</$wikify>
</$vars>
</$button>

Can’t use the double-curly within a filter - (around the !!title)

You wrote:

 \define Set_New_Tiddler()
 <$vars  un={{{ [{{!!title}}split[]first[7]last[2]join[]]  }}}>
 <$vars  an={{{ [{{!!title}}split[]first[14]last[1]join[]]  }}}>
 {{{ [[Some text]addsuffix<un>[some text]addsuffix<an>] }}}
 \end

Try this:

 \define Set_New_Tiddler()
 <$vars  un={{{ [{!!title}split[]first[7]last[2]join[]]  }}}>
 <$vars  an={{{ [{!!title}split[]first[14]last[1]join[]]  }}}>
 {{{ [[Some text]addsuffix<un>addsuffix[some text]addsuffix<an>] }}}
 \end

Notes:

  • in filters for un=… and an=…, change double curly braces to single curly braces
  • In filter for constructing new title, added “addsuffix” before 2nd [some text]

Let me know how it goes…

-e

That got it. Thanks.
Took me a few frustrating moment to work out that I wasn’t getting the correct letters returned because when your editing a tiddler the title becomes ‘Draft of…’!

So now I can set my assignment dates, and from there create a separate deadlines tiddler (so I can have a timeline of deadline dots) and easily update the deadline with the push of a button!
Using Klixams date picker (Date Picker plugin — based on Pikaday) and time line (vis.js Timeline — emkay plugin, reloaded) and Erics timer tools (It's About Time! — TiddlyTools: "Small Tools for Big Ideas!" (tm)).
Working in 5.2.0-prerelease

Next stop…templates :slight_smile:

The finished macro:

\define Set_New_Tiddler()
<$vars  un={{{ [{!!title}split[]first[7]last[2]join[]]  }}}>
<$vars  an={{{ [{!!title}split[]first[13]last[1]join[]]  }}}>
<!-- Rearange title-->
<$vars   un={{{ [<un>pad[2]] }}}>
{{{ [[Deadline: U]addsuffix<un>addsuffix[A]addsuffix<an>] }}}
\end

and the button to set it all:

<$button>Set Deadline
<$vars Title={{!!Title}} time={{!!timeline.end}} offset="-07:29">
<$wikify name="newname" text=<<Set_New_Tiddler>>>
<$wikify name="newtime" text=<<adjust_time>>>
<$action-setfield deadline=<<newtime>> />
<$action-setfield $tiddler=<<newname>>
timeline.end=<<newtime>>
timeline.start=<<newtime>>
tags='Deadline Schedule' />
</$wikify>
</$wikify>
</$vars>
</$button>

Start Date:
<$edit-date field="timeline.start" format="Do MMM YYYY" fieldFormat="YYYYMMDD00mm"/>


End Date:
<$edit-date field="timeline.end" format="Do MMM YYYY" fieldFormat="YYYYMMDD2359"/>

Deadline: ''<$view field="deadline" format="date" template="ddd DDth MMM YYYY at hh:mm"/>''

I assume that the <<adjust_time>> macro you are using is based on this post I made in the GoogleGroups on July 4, 2021: https://groups.google.com/g/tiddlywiki/c/uB1RxGj2qz0/m/aULGi1V9AgAJ

For completeness, I have copied that post here (and added a bit of formatting for Discourse)

On Sunday, July 4, 2021 at 1:09:10 PM UTC-7 Mohamed...@hotmail.com wrote:

I have a field in a tiddler that has a date value, i would like to have button to add one hour to the date value , is this possible ?

By “date value”, do you actually mean a full “datetime” value, which in TW is stored as a 17-digit number (YYYYMMDDhhmmssXXX)? Assuming that is the case, it can be done, but it’s not as simple as it may seem.

For instance, if the stored datetime is 20210704133000000 (i.e., 1:30pm on July 4, 2021), then it is relatively easy (though not trivial) to add an hour, like this:

<$button> add an hour
<$vars
   before={{{ [{!!stored_datetime}split[]first[8]join[]] }}}
   hour={{{ [{!!stored_datetime}split[]rest[8]first[2]join[]] }}}
   after={{{ [{!!stored_datetime}split[]rest[10]join[]] }}}>
<$vars newhour={{{ [<hour>add[1]pad[2]] }}}>
<$action-setfield stored_datetime={{{ [<before>addsuffix<newhour>addsuffix<after>] }}} />
</$vars>
</$vars>
</$button>
  • First, break the datetime value into parts to isolate the hour number:
    • Use split[] to break the datetime value into individual digits, and join the first[8] digits to get the date portion.
    • Use rest[8] to get the remaining digits and join the first[2] of those digits to get the hour number.
    • Use rest[10] to get the digits following the hour number, and join those to get the minutes, seconds and millisecond portion.
  • Next, add 1 to the hour number and apply pad[2] to the result to ensure it is 2 digits with a leading 0 if needed.
  • Then, reassemble the parts to give the new datetime value and update the field value.

However… this is not sufficient to handle all possible stored_datetime values.

For example, suppose that the stored datetime is 20210704233000000 (i.e., 11:30pm on July 4, 2021). Simply adding an hour as shown above would give 20210704243000000. But that is not a valid datetime value, as the hours portion must be between 00 and 23. The correct result would actually be 20210705003000000 (i.e., 12:30am on July 5, 2021). Thus, we need to handle “hour overflow” to set the hour number to 00 and add 1 to the day number.

But… even that is not enough. Suppose the stored datetime is 20210731233000000 (i.e., 11:30pm on July 31, 2021). Then adding 1 hour should result in 20210801003000000 (i.e., 12:30am on August 1, 2021). Thus, we not only need to handle “hour overflow” as above, but also “date overflow” to add 1 to the month number.

Complicating this is that the number of days per month varies, so the “date overflow” handling needs to take into account the specified month to know how many days it has. Further complicating this is leap years, in which the number of days in February is 29 rather than 28, but only for years that are divisible by 4 but not divisible by 100, unless also divisible by 400.

Lastly, we need also to handle “year overflow”. If the stored datetime is 20211231233000000 (i.e., 11:30pm on December 31, 2021). Then adding 1 hour should result in 20220101003000000 (i.e., 12:30am on January 1, 2022).

Obviously, handling all of these issues requires some complex conditional calculations. Fortunately, I’ve already tackled this problem in http://tiddlytools.com/timer.html#TiddlyTools%2FTime%2FClocks.

The clock_adjustForTimezone() macro takes the current datetime and adds or subtracts a “timezone offset” value to give a new datetime value. For your purposes, rather than using the current datetime, you want to get the stored_datetime value, and instead of using a “timezone offset”, you want to use a specified offset of 1 hour (i.e., “+01:00”)

Here’s a modified version of clock_adjustForTimezone() that does what you need:

\define adjust_time()
\whitespace trim
<!-- split time into parts -->
<$vars   yyyy={{{ [<time>split[]first[4]join[]]         }}}>
<$vars     mm={{{ [<time>split[]first[6]last[2]join[]]  }}}>
<$vars     dd={{{ [<time>split[]first[8]last[2]join[]]  }}}>
<$vars     hh={{{ [<time>split[]first[10]last[2]join[]] }}}>
<$vars    min={{{ [<time>split[]first[12]last[2]join[]] }}}>
<$vars  ssxxx={{{ [<time>split[]last[5]join[]]          }}}>
<!-- apply offset "+hh:mm" or "-hh:mm" -->
<$vars   sign={{{ [<offset>split[]first[]]                      }}}>
<$vars  offhh={{{ [<offset>split[]first[3]join[]]               }}}>
<$vars offmin={{{ [<offset>split[]last[2]join[]addprefix<sign>] }}}>
<$vars     hh={{{ [<hh>add<offhh>]   }}}>
<$vars    min={{{ [<min>add<offmin>] }}}>
<!-- adjust days per month for leap year -->
<$set name="leap" value={{{ [<yyyy>remainder[4]match[0]then[yes]] }}}>
<$set name="dpm"  value="31 28 31 30 31 30 31 31 30 31 30 31"> <!-- days per month -->
<$set name="dpm"  filter="[<leap>!match[]]" value="31 29 31 30 31 30 31 31 30 31 30 31" emptyValue=<<dpm>>>
<!-- adjust hours/minutes for minutes wraparound -->
<$set name="hh"   filter="[<min>compare:integer:lt[0]]"    value={{{ [<hh>subtract[1]]      }}} emptyValue=<<hh>>>
<$set name="hh"   filter="[<min>compare:integer:gteq[60]]" value={{{ [<hh>add[1]]           }}} emptyValue=<<hh>>>
<$set name="min"  filter="[<min>compare:integer:lt[0]]"    value={{{ [<min>add[60]]         }}} emptyValue=<<min>>>
<$set name="min"  filter="[<min>compare:integer:gteq[60]]" value={{{ [<min>subtract[60]]    }}} emptyValue=<<min>>>
<!-- adjust date/hours for hours wraparound -->
<$set name="dd"   filter="[<hh>compare:integer:lt[0]]"     value={{{ [<dd>subtract[1]]      }}} emptyValue=<<dd>>>
<$set name="dd"   filter="[<hh>compare:integer:gteq[24]]"  value={{{ [<dd>add[1]]           }}} emptyValue=<<dd>>>
<$set name="hh"   filter="[<hh>compare:integer:lt[0]]"     value={{{ [<hh>add[24]]          }}} emptyValue=<<hh>>>
<$set name="hh"   filter="[<hh>compare:integer:gteq[24]]"  value={{{ [<hh>subtract[24]]     }}} emptyValue=<<hh>>>
<!-- adjust month/date for date wraparound -->
<$set name="dm"   value={{{ [<dpm>split[ ]nth<mm>] }}}> <!-- days in this month -->
<$set name="mm"   filter="[<dd>compare:integer:lteq[0]]"   value={{{ [<mm>subtract[1]]      }}} emptyValue=<<mm>>>
<$set name="mm"   filter="[<dd>compare:integer:gt<dm>]"    value={{{ [<mm>add[1]]           }}} emptyValue=<<mm>>>
<$set name="dd"   filter="[<dd>compare:integer:lteq[0]]"   value={{{ [<dpm>split[ ]nth<mm>] }}} emptyValue=<<dd>>>
<$set name="dd"   filter="[<dd>compare:integer:gt<dm>]"    value={{{ [[1]]                  }}} emptyValue=<<dd>>>
<!-- adjust year/date/month for month wraparound -->
<$set name="yyyy" filter="[<mm>compare:integer:lteq[0]]"   value={{{ [<yyyy>subtract[1]]    }}} emptyValue=<<yyyy>>>
<$set name="yyyy" filter="[<mm>compare:integer:gt[12]]"    value={{{ [<yyyy>add[1]]         }}} emptyValue=<<yyyy>>>
<$set name="dd"   filter="[<mm>compare:integer:lteq[0]]"   value={{{ [[31]]                 }}} emptyValue=<<dd>>>
<$set name="dd"   filter="[<mm>compare:integer:gt[12]]"    value={{{ [[1]]                  }}} emptyValue=<<dd>>>
<$set name="mm"   filter="[<mm>compare:integer:lteq[0]]"   value={{{ [[12]]                 }}} emptyValue=<<mm>>>
<$set name="mm"   filter="[<mm>compare:integer:gt[12]]"    value={{{ [[1]]                  }}} emptyValue=<<mm>>>
<!-- zero-pad and assemble new time -->
<$vars   mm={{{ [<mm>pad[2]] }}} dd={{{ [<dd>pad[2]] }}} hh={{{ [<hh>pad[2]] }}} min={{{ [<min>pad[2]] }}}>
{{{ [<yyyy>addsuffix<mm>addsuffix<dd>addsuffix<hh>addsuffix<min>addsuffix<ssxxx>] }}}
\end

and here’s a button that invokes the above to update the stored_datetime field value:

<$button> add an hour
<$vars time={{!!stored_datetime}} offset="+01:00">
<$wikify name="newtime" text=<<adjust_time>>>
<$action-setfield stored_datetime=<<newtime>> />
</$wikify>
</$vars>
</$button>

enjoy,
-e

2 Likes

Yes that’s the one. Thanks once again Eric.