From: Thomas Walker Lynch Date: Fri, 28 Aug 2026 07:13:35 +0000 (+0000) Subject: counters name can now be a list X-Git-Url: https://git.reasoningtechnology.com/Realizable_Machine.svg?a=commitdiff_plain;h=refs%2Fheads%2Fcore-developer_branch;p=RT-Style counters name can now be a list --- diff --git a/developer/authored/Manuscript.copy/Document/design.html b/developer/authored/Manuscript.copy/Document/design.html index 717b3b0..7d39fef 100644 --- a/developer/authored/Manuscript.copy/Document/design.html +++ b/developer/authored/Manuscript.copy/Document/design.html @@ -915,7 +915,10 @@

- The default counter is named Chapter, and the others in dict_counter are Front Matter and Appendix. These names are not internal: a cross reference reads the counter's name to print the word in front of the number, so what a counter is called is what the reader sees. Counters are named for print, and a name that would embarrass a page is the wrong name. + The default counter is named Chapter,Section, and the others in dict_counter are Front Matter,Front Matter Section and Appendix,Appendix Section. These names are not internal: a cross reference reads the counter's name to print the word in front of the number, so what a counter is called is what the reader sees. Counters are named for print, and a name that would embarrass a page is the wrong name. +

+

+ A name is a comma separated list, resolved by depth with the last entry repeating, and read('counter') chooses from it using the same active list that to_string uses to choose a style. The word and the number are therefore taken from one source, and cannot disagree at a scope boundary: a snapshot taken in a chapter after a subsection has closed reads Chapter 12, not Section 12. The whole string remains the counter's identity in dict_instance, so nesting and inheritance are untouched; only the word selected from the list varies. This replaces the earlier prefix attribute, which carried the same list on a second field that could disagree with the name.

diff --git a/developer/authored/Manuscript.copy/Document/user.html b/developer/authored/Manuscript.copy/Document/user.html index 1bcdf67..c5b36d1 100644 --- a/developer/authored/Manuscript.copy/Document/user.html +++ b/developer/authored/Manuscript.copy/Document/user.html @@ -302,13 +302,13 @@ The divisions of a book are not one sequence. A single counter across the whole manuscript would number the preface as chapter one and start the appendices wherever the last chapter left off. So each division names its own counter, and the counter's name is the word the reader sees.

- + The default. Counting numbers at every level: 1, then 1.1, then 1.1.1. - + Lower case roman: i, then i.ii. - + Upper case letters at the top level and counting numbers below: A, then A.1. @@ -331,6 +331,9 @@

Counters are named for print. A cross reference reads the counter's name to print the word in front of the number, so a name that would embarrass a page is the wrong name.

+

+ A name can be a comma separated list, which names the counter differently at different depths with the last name repeating. That is why the default is written Chapter,Section: a reference to a top level section reads Chapter 12, and one to a section inside it reads Section 12.3, from the same read written the same way. The whole string is the counter's identity, so every section of a division still steps the one counter and nesting is unaffected; only the word chosen from the list varies with depth. +

A counter named on a section but not in the table is still made, on the default numbering. That is how a second appendix sequence or a numbered part is introduced with no configuration at all. To give a new counter a style of its own, add an entry before the document is processed. Put it in a second script element in the head, after the loads, so that the section element has been loaded by the time it runs:

@@ -384,11 +387,14 @@ The formatted number, styled and separated as the counter was configured. This is the default. - The name of the counter, which is the word that belongs in front of the number: Chapter, Appendix, Figure. + The name of the counter, which is the word that belongs in front of the number: Chapter, Appendix, Figure. When the counter was named with a comma separated list, the name is chosen by the depth of the snapshot, with the last name repeating: Chapter,Section reads Chapter at the top level and Section below it. The name of the step, which for a section is its title. + + The counter's name as it was written, list and all, without choosing by depth. Diagnostic. + The raw level numbers, comma separated, unformatted. Diagnostic. @@ -477,7 +483,7 @@ Make attributes - Required. The counter's name, and the word a reference prints in front of the number. + Required. The counter's name, and the word a reference prints in front of the number. A comma separated list names the counter by depth, with the last name repeating. Comma separated, one per nesting level, the last repeating. Default: NaturalNumber. diff --git a/developer/authored/Manuscript.copy/Element/section.js b/developer/authored/Manuscript.copy/Element/section.js index 32b2fe5..1f2a1c3 100644 --- a/developer/authored/Manuscript.copy/Element/section.js +++ b/developer/authored/Manuscript.copy/Element/section.js @@ -24,36 +24,43 @@ sees: a cross reference written key="counter count" against a counter named 'Appendix' prints 'Appendix B'. Counters are named for print. + A name can be a comma separated list ,which names the counter differently + at different depths with the last name repeating. 'Chapter,Section' prints + 'Chapter 12' at the top level and 'Section 12.3' below it. The whole + string is the counter's identity ,so every section of a division inherits + it and they all step the one counter; only the word chosen from it varies + with depth. + This table holds the make configuration of the counters the section element creates ,keyed by counter name. It is open. An author wanting a numbered part ,or a second appendix sequence ,adds an entry before the element phase runs: - RT.Element.Section.dict_counter['Part'] = + RT.Element.Section.dict_counter['Part,Chapter'] = { style: 'Roman' ,on_first_step: 'I' }; - and writes . A counter named on a section but - absent from the table is still made ,on the default configuration: the - table varies the style ,it does not gate the name. Sections nested inside - a section inherit its counter ,so the attribute is written once at the top - of a division and not repeated. + and writes . A counter named on a + section but absent from the table is still made ,on the default + configuration: the table varies the style ,it does not gate the name. + Sections nested inside a section inherit its counter ,so the attribute is + written once at the top of a division and not repeated. */ ns.dict_counter = { - 'Chapter': { + 'Chapter,Section': { style: 'CountingNumber' ,on_first_step: '0' } - ,'Front Matter': { + ,'Front Matter,Front Matter Section': { style: 'roman' ,on_first_step: 'i' } - ,'Appendix': { + ,'Appendix,Appendix Section': { style: 'Alpha,CountingNumber' ,on_first_step: 'A' } }; - ns.counter_default = 'Chapter'; + ns.counter_default = 'Chapter,Section'; /* The counter is written on the outermost section of a division. Read it from the nearest ancestor that has one. diff --git a/developer/authored/Manuscript.copy/Layout/counter.js b/developer/authored/Manuscript.copy/Layout/counter.js index c4e9488..1077994 100644 --- a/developer/authored/Manuscript.copy/Layout/counter.js +++ b/developer/authored/Manuscript.copy/Layout/counter.js @@ -174,6 +174,13 @@ this.mode = 'scoped'; /* The counter's own name ,the key it is filed under in dict_instance. + + A comma separated list names the counter differently at different + depths ,with the last name repeating: 'Chapter,Section' answers + Chapter at the top level and Section at every level below it. The word + in front of a number is the counter's name at that depth ,not a + separate thing to configure. + Held on the machine so that a snapshot ,which is a clone cut loose from the dictionary ,can still say what it counts. */ this.counter = ''; @@ -189,6 +196,14 @@ return this.count.read(...path.slice(1)); } + /* The counter's name at the depth in force. A single name answers at + every depth; a list answers by depth. 'counter.list' returns the name + as written ,for a caller that wants the whole list. */ + if(path[0] === 'counter'){ + if(path[1] === 'list') return this.counter; + return this.counter_for(this.count); + } + /* The name of the step in force. Taken from the level the number is taken from ,or the two would disagree at a scope boundary. */ if(path[0] === 'step'){ @@ -264,6 +279,36 @@ : c.read('list'); } + /* The counter's name ,parsed. Held on the machine as the string it was + made under ,so that identity and clone stay one field ,and split here + on the few occasions a name is read. */ + name_seq(){ + return String(this.counter || '') + .split(',') + .map(s => s.trim()) + .filter(s => s !== ''); + } + + /* 'Chapter' at the top ,'Section' below it. Chosen by depth ,with the last + entry repeating ,so a two name list covers a document nested to any + depth. The depth is taken from the same active list the number is taken + from ,or the word and the number would disagree at a scope boundary. + + A counter that has taken no step has no depth to speak of ,and answers + with its top level name: a counter has a name whether or not it has yet + counted anything. */ + counter_for(count_obj){ + const name_seq = this.name_seq(); + if(name_seq.length === 0) return ''; + + const active_list = this.active_list_of(count_obj); + const depth = (!active_list || active_list.length === 0) + ? 0 + : Math.min(active_list.length ,name_seq.length) - 1; + + return name_seq[depth] || ''; + } + to_string(count_obj){ if(!count_obj) return ''; @@ -498,8 +543,9 @@ /* One field of a read. 'count' is the formatted number ,and anything else is a path into the machine ,written with dots: 'counter' for the name of - the counter ,'step' for the name of the step ,'count.list' ,'count.name' - and 'count.status' for the raw state. */ + the counter at the depth in force ,'step' for the name of the step ,and + 'counter.list' ,'count.list' ,'count.name' ,'count.status' for the raw + state. */ function read_field(machine ,field){ if(field === 'count'){ return machine.to_string(machine.read('count'));