View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001974 | 1003.1(2024)/Issue8 | Shell and Utilities | public | 2026-03-11 15:00 | 2026-03-14 01:15 |
| Reporter | mkoskar | Assigned To | |||
| Priority | normal | Severity | Objection | Type | Error |
| Status | New | Resolution | Open | ||
| Name | Miroslav Koškár | ||||
| Organization | |||||
| User Reference | |||||
| Section | 3 Utilities / tabs | ||||
| Page Number | 3415 | ||||
| Line Number | 116444-116446 | ||||
| Interp Status | |||||
| Final Accepted Text | |||||
| Summary | 0001974: tabs: wrong description of semantics of arbitrary tab stops | ||||
| Description | To get tab stops with a standard interval of 8: $ tabs -8 Analogous to that when arbitrary tab stops are used: $ tabs 1,9,17,25 Tab stop value: * is > 0 * represents a column (left-most being 1) where cursor moves and output occurs after preceding \t character * as a special case, the 1st tab stop value is always 1 (whether explicitly specified or not) to demonstrate that without preceding \t character output occurs in the left-most column The above is true for most common implementation of tabs from ncurses. I believe that indicated sentence: > The phrase "tab-stop position N" shall be taken to mean that, from the start of a line of output, tabbing to position N shall cause the next character output to be in the (N+1)th column position on that line. is wrong with regards to what actual semantics of operand(s) is. For additional context, this came up in following: * https://github.com/gwsw/less/issues/737 I've tried to summarize in following comment: * https://github.com/gwsw/less/issues/737#issuecomment-4033517061 Further of note are comments by @avih who were instrumental in tracking down historical sources of tabs and its documentation. | ||||
| Desired Action | Remove following sentence from the DESCRIPTION section: > The phrase "tab-stop position N" shall be taken to mean that, from the start of a line of output, tabbing to position N shall cause the next character output to be in the (N+1)th column position on that line. In OPERANDS section add following lines (demarcated with +++): n[[sep[+]n]...] A single command line argument that consists of one or more tab-stop values (n) separated by a separator character (sep) which is either a <comma> or a <blank> character. The application shall ensure that the tab-stop values are positive decimal integers in strictly ascending order. +++ A tab-stop value shall be taken to mean a column (left-most being 1) where cursor moves and output occurs after preceding \t character. The 1st tab-stop value is always 1 (whether explicitly specified or not) to demonstrate that without preceding \t character output occurs in the left-most column. +++ If any tab-stop value (except the first one) is preceded by a <plus-sign>, it is taken as an increment to be added to the previous value. For example, the tab lists 1,10,20,30 and "1 10 +10 +10" are considered to be identical. | ||||
| Tags | No tags attached. | ||||
|
|
Correction: I meant to reference following comment https://github.com/gwsw/less/issues/737#issuecomment-4030159904 instead. |
|
|
I think the terms left and right should be avoided, since such directions do not account for right-to-left scripts (in tbe Unicode sense of the term). "Beginning of line" and "end of line" might be better? |
|
|
Column-1 is the first available position for a tab stop on a line. An (ECMA-48 compatible) terminal can be set up so that the first tab stop on a line is not on the first column. The tabs program is documented to take this into account. Given that (and spelling), the sentence "The 1st tab-stop value is always 1 (whether explicitly specified or not) to demonstrate that without preceding \t character output occurs in the left-most column." needs some revision. Rather than removing the obscurely-worded sentence with "tabbing to position N", it should be revised to explain that tab-stops are 1-based, and that while the interval between stops may be 8, the 1-based detail makes the stops one column past the simple multiple of the tab interval. (making that both concise and clear doesn't look simple -- but the existing description is concise) |
|
|
My main objection to the sentence > The phrase "tab-stop position N" shall be taken to mean that, from the start > of a line of output, tabbing to position N shall cause the next character output > to be in the (N+1)th column position on that line. is that it implies that doing e.g., $ N=9 ; tabs 1,$N ; printf '\tX\n' causes the letter "X" to be printed in the column (N+1)=10, instead of 9 (which is in fact what happens). So in keeping changes as minimal as possible, an alternative fix is amending the above sentence and replacing "(N+1)th column" with "Nth column". Note that the reason why the variation of above sentence works for expand/unexpand is that "-t tablist" option in those utilities takes 0-based tab stops but here tab stops are 1-based as @dickey also pointed out. |
|
|
Regarding "expand" versus 1-based or 0-based, it states in https://pubs.opengroup.org/onlinepubs/9799919799/utilities/expand.html Each tab stop N shall be an integer value greater than zero, and the list is in strictly ascending order. which is 1-based. |
|
|
Regarding the tabbing to position N, I noticed an analogous issue in ECMA-48 section 8.3.61 (HTJ - character tabulation with justification) which describes behavior before the tab stop. The original authors of the document may have had something like that in mind, distinguish the tab movement (all whitespace) from the position where the next character would be printed. Since (without being familiar with terminals at that level), readers can get confused, the goal here seems to be to rephrase things in clearer language without changing the underlying technical content. |
|
|
> which is 1-based. Ah right, granted, I should have said as-if-0-based, at least that's how I think about it. Alternatively one can look at it such that "tab stop N" is either where: 1) N refers to column on which the next character should be printed. or 2) N refers to column after which the next character should printed. With regards to difference of e.g., `tabs 1,9,17` and `tabs 9,17` I stand corrected. I assumed 1 is always implied. Investigating its output e.g., via `xxd` or `od` reveals that latter does not put a tab stop on 1. |
|
|
ECMA-48 https://ecma-international.org/publications-and-standards/standards/ecma-48/ standard for terminal controls (including cursor movement and tab stops) numbers columns starting at 1. The (presumably) AT&T people who documented tabs had that in mind. The tab stops are the columns on which the first character is printed after tabbing to that column. There's some possible confusion over what happens with the column just before the tab stop (because it may appear that the the tab "must" go there. But it doesn't happen that way. The terminal simply skips over the intervening columns (without modifying them) to prepare to show a printable character at the tab stop. (If something other than a printable character follows, that's outside the scope of this document, and is "unspecified"). |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-03-11 15:00 | mkoskar | New Issue | |
| 2026-03-11 15:10 | mkoskar | Note Added: 0007395 | |
| 2026-03-11 17:02 | wpollock | Note Added: 0007396 | |
| 2026-03-11 19:39 | dickey | Note Added: 0007397 | |
| 2026-03-11 21:56 | mkoskar | Note Added: 0007398 | |
| 2026-03-11 22:29 | dickey | Note Added: 0007399 | |
| 2026-03-11 22:40 | dickey | Note Added: 0007400 | |
| 2026-03-13 09:49 | mkoskar | Note Added: 0007403 | |
| 2026-03-14 01:15 | dickey | Note Added: 0007406 |