Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-128317: Highlight today in colour in calendar CLI output#128318
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
e6906073608954ad2921ce31133f2749ff8a565d97File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -146,46 +146,61 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is | ||
| the specified width, representing an empty day. The *weekday* parameter | ||
| is unused. | ||
| .. method:: formatweek(theweek, w=0) | ||
| .. method:: formatweek(theweek, w=0, highlight_day=None) | ||
| Return a single week in a string with no newline. If *w* is provided, it | ||
| specifies the width of the date columns, which are centered. Depends | ||
| on the first weekday as specified in the constructor or set by the | ||
| :meth:`setfirstweekday` method. | ||
| .. versionchanged:: next | ||
| If *highlight_day* is given, this date is highlighted in color. | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this say “using terminal escape sequences”? MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I think it's more useful to describe the end result rather than the "how". Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was my intention: mention that you need to print the result to a terminal to see the highlight. If you don't, you'll see some garbage bytes. | ||
| This can be :ref:`controlled using environment variables | ||
| <using-on-controlling-color>`. | ||
| .. method:: formatweekday(weekday, width) | ||
| Return a string representing the name of a single weekday formatted to | ||
| the specified *width*. The *weekday* parameter is an integer representing | ||
| the day of the week, where ``0`` is Monday and ``6`` is Sunday. | ||
| .. method:: formatweekheader(width) | ||
| Return a string containing the header row of weekday names, formatted | ||
| with the given *width* for each column. The names depend on the locale | ||
| settings and are padded to the specified width. | ||
| .. method:: formatmonth(theyear, themonth, w=0, l=0) | ||
| .. method:: formatmonth(theyear, themonth, w=0, l=0, highlight_day=None) | ||
| Return a month's calendar in a multi-line string. If *w* is provided, it | ||
| specifies the width of the date columns, which are centered. If *l* is | ||
| given, it specifies the number of lines that each week will use. Depends | ||
| on the first weekday as specified in the constructor or set by the | ||
| :meth:`setfirstweekday` method. | ||
| .. versionchanged:: next | ||
| If *highlight_day* is given, this date is highlighted in color. | ||
| This can be :ref:`controlled using environment variables | ||
| <using-on-controlling-color>`. | ||
| .. method:: formatmonthname(theyear, themonth, width=0, withyear=True) | ||
| Return a string representing the month's name centered within the | ||
| specified *width*. If *withyear* is ``True``, include the year in the | ||
| output. The *theyear* and *themonth* parameters specify the year | ||
| and month for the name to be formatted respectively. | ||
| .. method:: prmonth(theyear, themonth, w=0, l=0) | ||
| Print a month's calendar as returned by :meth:`formatmonth`. | ||
| .. method:: formatyear(theyear, w=2, l=1, c=6, m=3) | ||
| .. method:: formatyear(theyear, w=2, l=1, c=6, m=3, highlight_day=None) | ||
| Return a *m*-column calendar for an entire year as a multi-line string. | ||
| Optional parameters *w*, *l*, and *c* are for date column width, lines per | ||
| @@ -194,6 +209,11 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is | ||
| :meth:`setfirstweekday` method. The earliest year for which a calendar | ||
| can be generated is platform-dependent. | ||
| .. versionchanged:: next | ||
| If *highlight_day* is given, this date is highlighted in color. | ||
| This can be :ref:`controlled using environment variables | ||
| <using-on-controlling-color>`. | ||
| .. method:: pryear(theyear, w=2, l=1, c=6, m=3) | ||
| @@ -549,7 +569,7 @@ The :mod:`calendar` module defines the following exceptions: | ||
| .. _calendar-cli: | ||
| Command-Line Usage | ||
| Command-line usage | ||
hugovk marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| ------------------ | ||
| .. versionadded:: 2.5 | ||
| @@ -687,6 +707,9 @@ The following options are accepted: | ||
| The number of months printed per row. | ||
| Defaults to 3. | ||
| .. versionchanged:: next | ||
| By default, today's date is highlighted in color and can be | ||
| :ref:`controlled using environment variables <using-on-controlling-color>`. | ||
| *HTML-mode options:* | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -349,11 +349,27 @@ def formatday(self, day, weekday, width): | ||
| s = '%2i' % day # right-align single-digit days | ||
| return s.center(width) | ||
| def formatweek(self, theweek, width): | ||
| def formatweek(self, theweek, width, *, highlight_day=None): | ||
| """ | ||
| Returns a single week in a string (no newline). | ||
| """ | ||
| return ' '.join(self.formatday(d, wd, width) for (d, wd) in theweek) | ||
| if highlight_day: | ||
| from _colorize import get_colors | ||
| ansi = get_colors() | ||
| highlight = f"{ansi.BLACK}{ansi.BACKGROUND_YELLOW}" | ||
| reset = ansi.RESET | ||
| else: | ||
| highlight = reset = "" | ||
| return ' '.join( | ||
| ( | ||
| f"{highlight}{self.formatday(d, wd, width)}{reset}" | ||
| if d == highlight_day | ||
| else self.formatday(d, wd, width) | ||
| ) | ||
| for (d, wd) in theweek | ||
| ) | ||
hugovk marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. hugovk marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| def formatweekday(self, day, width): | ||
| """ | ||
| @@ -388,10 +404,11 @@ def prmonth(self, theyear, themonth, w=0, l=0): | ||
| """ | ||
| print(self.formatmonth(theyear, themonth, w, l), end='') | ||
| def formatmonth(self, theyear, themonth, w=0, l=0): | ||
| def formatmonth(self, theyear, themonth, w=0, l=0, *, highlight_day=None): | ||
| """ | ||
| Return a month's calendar string (multi-line). | ||
| """ | ||
| highlight_day = highlight_day.day if highlight_day else None | ||
| w = max(2, w) | ||
| l = max(1, l) | ||
| s = self.formatmonthname(theyear, themonth, 7 * (w + 1) - 1) | ||
| @@ -400,11 +417,11 @@ def formatmonth(self, theyear, themonth, w=0, l=0): | ||
| s += self.formatweekheader(w).rstrip() | ||
| s += '\n' * l | ||
| for week in self.monthdays2calendar(theyear, themonth): | ||
| s += self.formatweek(week, w).rstrip() | ||
| s += self.formatweek(week, w, highlight_day=highlight_day).rstrip() | ||
| s += '\n' * l | ||
| return s | ||
| def formatyear(self, theyear, w=2, l=1, c=6, m=3): | ||
| def formatyear(self, theyear, w=2, l=1, c=6, m=3, *, highlight_day=None): | ||
| """ | ||
| Returns a year's calendar as a multi-line string. | ||
| """ | ||
| @@ -428,15 +445,24 @@ def formatyear(self, theyear, w=2, l=1, c=6, m=3): | ||
| headers = (header for k in months) | ||
| a(formatstring(headers, colwidth, c).rstrip()) | ||
| a('\n'*l) | ||
| if highlight_day and highlight_day.month in months: | ||
| month_pos = months.index(highlight_day.month) | ||
| else: | ||
| month_pos = None | ||
| # max number of weeks for this row | ||
| height = max(len(cal) for cal in row) | ||
| for j in range(height): | ||
| weeks = [] | ||
| for cal in row: | ||
| for k, cal in enumerate(row): | ||
| if j >= len(cal): | ||
| weeks.append('') | ||
| else: | ||
| weeks.append(self.formatweek(cal[j], w)) | ||
| day = highlight_day.day if k == month_pos else None | ||
| weeks.append( | ||
| self.formatweek(cal[j], w, highlight_day=day) | ||
| ) | ||
| a(formatstring(weeks, colwidth, c).rstrip()) | ||
| a('\n' * l) | ||
| return ''.join(v) | ||
| @@ -765,6 +791,7 @@ def main(args=None): | ||
| sys.exit(1) | ||
| locale = options.locale, options.encoding | ||
| today = datetime.date.today() | ||
ZeroIntensity marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if options.type == "html": | ||
| if options.month: | ||
| @@ -781,7 +808,7 @@ def main(args=None): | ||
| optdict = dict(encoding=encoding, css=options.css) | ||
| write = sys.stdout.buffer.write | ||
| if options.year is None: | ||
| write(cal.formatyearpage(datetime.date.today().year, **optdict)) | ||
| write(cal.formatyearpage(today.year, **optdict)) | ||
| else: | ||
| write(cal.formatyearpage(options.year, **optdict)) | ||
| else: | ||
| @@ -797,10 +824,15 @@ def main(args=None): | ||
| if options.month is not None: | ||
| _validate_month(options.month) | ||
| if options.year is None: | ||
| result = cal.formatyear(datetime.date.today().year, **optdict) | ||
| optdict["highlight_day"] = today | ||
| result = cal.formatyear(today.year, **optdict) | ||
| elif options.month is None: | ||
| if options.year == today.year: | ||
| optdict["highlight_day"] = today | ||
| result = cal.formatyear(options.year, **optdict) | ||
| else: | ||
| if options.year == today.year and options.month == today.month: | ||
| optdict["highlight_day"] = today | ||
| result = cal.formatmonth(options.year, options.month, **optdict) | ||
| write = sys.stdout.write | ||
| if options.encoding: | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Highlight today in colour in :mod:`calendar`'s CLI output. Patch by Hugo van | ||
| Kemenade. |
Uh oh!
There was an error while loading. Please reload this page.