Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time tag #21

Draft
wants to merge 1 commit into
base: cactus
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions markup.css
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,14 @@ L + ratio { }
display: none;
}

/**********/
/** Time **/
/**********/
.Markup time {
text-decoration: dotted underline;
cursor: help;
}

/***********/
/** Quote **/
/***********/
Expand Down
15 changes: 14 additions & 1 deletion parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Markup_12y2 { constructor() {

// About __proto__ in object literals:
// https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-propertydefinitionevaluation
const IS_BLOCK = {__proto__:null, code:'block', divider:'block', ROOT:'block', heading:'block', quote:'block', table:'block', table_cell:'block', image:'block', video:'block', audio:'block', spoiler:'block', align:'block', list:'block', list_item:'block', youtube:'block', anchor:'block', table_divider:'block', ruby:'text', key:'text'}
const IS_BLOCK = {__proto__:null, code:'block', divider:'block', ROOT:'block', heading:'block', quote:'block', table:'block', table_cell:'block', image:'block', video:'block', audio:'block', spoiler:'block', align:'block', list:'block', list_item:'block', youtube:'block', anchor:'block', table_divider:'block', ruby:'text', key:'text', time:'text'}
// 'text' is for inline-block elements


Expand Down Expand Up @@ -477,6 +477,19 @@ class Markup_12y2 { constructor() {
let [txt="true"] = rargs
OPEN('ruby', {text: txt})
word_maybe()
} break; case '\\time': {
let [timestamp, style] = rargs
if (!/^[tTdDfFR]$/.test(style))
style = 'f'
if (/^\d+(.\d+)?$/.test(timestamp)) {
timestamp = Number.parseFloat(timestamp) * 1000
} else {
timestamp = Date.parse(timestamp)
}
if (Number.isNaN(timestamp))
timestamp = 0
timestamp = new Date(timestamp)
BLOCK('time', {timestamp, style})
} break; case '\\key': {
OPEN('key')
word_maybe()
Expand Down
88 changes: 88 additions & 0 deletions render.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,94 @@ we should create our own fake bullet elements instead.*/

key: 𐀶`<kbd>`,

time: function({timestamp, style}) {
let e = this()
/*
https://discord.com/developers/docs/reference#message-formatting-timestamp-styles
https://gist.github.com/LeviSnoot/d9147767abeef2f770e9ddcd91eb85aa
stealing syntax / formatting ideas from this

two types of timestamps are accepted:
- unix timestamps (entirely numeric)
- `Date.parse()` date+time strings

## Big overview
|default|`1719878490`|\time[1719878490]|
|time|\time[1719878490;t]|\time[1719878490;T]|
|date|\time[1719878490;d]|\time[1719878490;D]|
|full|\time[1719878490;f]|\time[1719878490;F]|
|rel.|\{}|\time[1719878490;R]|

## Short vs. Long forms
\time[2024-06-12 01:00 EST;f] / \time[2024-06-12 01:00 EST;F]
\time[2024-06-12 01:00 EST;t] / \time[2024-06-12 01:00 EST;T]
\time[2024-06-12 01:00 EST;d] / \time[2024-06-12 01:00 EST;D]

## Relative-to-render times
They have hover text!
\time[2024-06-12 01:00 EST;R]
Asdf \time[2024-06-12 19:46 EDT;R] asdf?
out \time[2024-06-12 18:46 EDT;R]?

## `Date.parse()` acts differently depending on whitespace
\time[2001-06-12;R]
\time[2001-06-12 ;R]
implies timezone was acknowledged? why..?

## Strange behavior with trailing `{` and whitespace in general
\time[2024-06-12 01:00 EST;f] a b c
\time[2024-06-12 01:00 EST;f]{ a b c
\time[2024-06-12 01:00 EST;f]{} a b c
\time[1719878400.01;f]{
\time[1719878400.99;f]{ fractions work!! (if you want that specificity)

## Expected End of Birthday
\time[1719878400;R]
\time[1718496000;R]
*/
if (timestamp instanceof Date) {
const locale = Intl.DateTimeFormat().resolvedOptions().locale
e.title = timestamp.toLocaleString()
switch (style) { default: { // TODO: this is embarrassing
e.textContent = timestamp.toUTCString()
} break; case 't': {
e.textContent = timestamp.toLocaleTimeString(locale, { 'timeStyle': 'short' })
} break; case 'T': {
e.textContent = timestamp.toLocaleTimeString(locale, { 'timeStyle': 'medium' })
} break; case 'd': {
e.textContent = timestamp.toLocaleDateString(locale, { 'dateStyle': 'short' })
} break; case 'D': {
e.textContent = timestamp.toLocaleDateString(locale, { 'dateStyle': 'medium' })
} break; case 'f': {
e.textContent = timestamp.toLocaleString() // ?
} break; case 'F': {
e.textContent = timestamp.toLocaleString()
} break; case 'R': {
const timez = [[1000, 'ms'], [60, 'seconds'], [60, 'minutes'], [24, 'hours'], [Infinity, 'days']]
let render = new Date() // makes static rendering bad...
let after_render = timestamp - render
e.title += `\nRendered at ${render.toLocaleTimeString()}`
// also i'm recreating code that already exists in the frontend..
for (let [level_up, metric] of timez) { // bad naming on purpose
if (Math.abs(after_render) > level_up) {
after_render /= level_up
} else {
after_render = Math.round(after_render * 10) / 10
if (after_render > 0)
e.textContent = `in ${after_render} ${metric}`
else
e.textContent = `${-after_render} ${metric} ago`
break
}
}
// oh hey i could just set a signal handler here to update this!!
}}
} else {
e.textContent = timestamp
}
return e
}.bind(𐀶`<time>`),

preview: function(node) {
let e = this()
e.textContent = node.type
Expand Down