13
$\begingroup$

The example cells in the documentation each have a count of the cells inside their section:

 Cell[TextData[{"Basic Examples", "  ", Cell["(4)", "ExampleCount"]}],
   "ExampleSection", "ExampleSection"]

But this is static content, how exactly would this work dynamically? I'd like to make my own cell style where the cell dingbat counts the number of cells inside the cell group it contains (and updates itself dynamically of course).

I've looked at the stylesheet for outline-styled notebooks and then tried using the Counter* options, but these are for dynamic tallying, not content counting and there's not much documentation on these esoteric front-end things like

CounterBoxOptions->{CounterFunction:>CapitalRomanNumeral}]

Any help would be appreciated.

enter image description here

$\endgroup$
4
  • $\begingroup$ Maybe you can setup a Notebook-level Dynamic object doing the counting, and just refer to its result at any place you want. (With the help of CellID/CellTags/etc. maybe.) $\endgroup$
    – Silvia
    Commented Feb 6, 2015 at 13:53
  • $\begingroup$ @Silvia Good idea, but I foresee a problem: If a Dynamic expression is not visible in the notebook's window (i.e. scrolled out of range) we are out of luck... And having that Dynamic always running impact performance? $\endgroup$
    – M.R.
    Commented Feb 6, 2015 at 16:17
  • 1
    $\begingroup$ That is why I think a Notebook-level Dynamic object (such as NotebookEventActions, NotebookDynamicExpression or similar) should be used, so as long as the nb is visible, the counter will work. About the performance, I'm sorry but I really can't come up with a way without Dynamic.. $\endgroup$
    – Silvia
    Commented Feb 7, 2015 at 3:18
  • $\begingroup$ I don't think you can do this with standard Counters since you would have to know the counter state before cells that are going to increment it. And it seems the notebook is read by the FE in one direction. $\endgroup$
    – Kuba
    Commented Nov 15, 2015 at 14:30

2 Answers 2

8
$\begingroup$

I think when it's done each time you save the notebook it should be nice enough :)

SetOptions[
 EvaluationNotebook[],
 NotebookEventActions -> {
   {"MenuCommand", "Save"} :> (Scan[
      Module[{nr},
        SelectionMove[#, All, CellGroup, AutoScroll -> False];
        nr = Length @ Select[
           SelectedCells[], 
           Experimental`CellStyleNames[#] === "Input" & (*1*)
        ];
        SetOptions[#, CellDingbat -> "(" <> ToString[nr] <> ")"];
      ] &
      ,
      Cells[CellStyle -> "Section"] (*2*)
   ]),
   PassEventsDown -> True
   }
 ]

Ad 1. Cell style to count

Ad 2. Cell style whose parent group end "resets the counter"

You can use it in stylesheets too.

enter image description here


Update from Question's Author:

As Kuba's comment fixes the raggedness:

SetOptions[EvaluationNotebook[], 
     NotebookEventActions -> {{"MenuCommand", 
         "Save"} :> (Scan[
          Module[{nr}, 
            SelectionMove[#, All, CellGroup, AutoScroll -> False];

            nr = Length@
              Select[SelectedCells[], 
               Experimental`CellStyleNames[#] === 
                 "ItemNumbered" & (*1*)];

            SetOptions[#, 
             CellDingbat -> 
              Cell[BoxData[
                PaneBox[
                 StyleBox[ToString[nr] <> "   ", 
                  RGBColor[0.5, 0.5, 0.67, 0.81], 
                  FontFamily -> "Continuum Light", 15], 
                 Alignment -> Right, ImageSize -> 40]], 
               Background -> White]];] &, 
          Cells[CellStyle -> "Subsection"] (*2*)]), 
       PassEventsDown -> True}]

enter image description here

$\endgroup$
12
  • $\begingroup$ This isn't a stylesheet though $\endgroup$
    – M.R.
    Commented Nov 19, 2015 at 14:53
  • $\begingroup$ @M.R. I must admit I have not tried but I though it should work as an option to StyleData[Notebook] Cell $\endgroup$
    – Kuba
    Commented Nov 19, 2015 at 14:56
  • $\begingroup$ Also it induces unwanted indentations. Maybe we could have a quick chat session $\endgroup$
    – M.R.
    Commented Nov 19, 2015 at 15:26
  • $\begingroup$ @M.R. I will try to address your questions later, I have to go offine atm. Do you want to include (5) after the cell content? $\endgroup$
    – Kuba
    Commented Nov 19, 2015 at 15:30
  • $\begingroup$ No its just that when the number varies in digit length, the left margins of section cells are all different and look ragged. $\endgroup$
    – M.R.
    Commented Nov 19, 2015 at 15:34
1
$\begingroup$

Here is a stylesheet solution that gives "Section" cells a dingbat that counts the number of "Input" cells in the section:

SetOptions[
    EvaluationNotebook[],
    StyleDefinitions -> Notebook[
        {
        Cell[StyleData[StyleDefinitions -> "Default.nb"]], 
        Cell[StyleData["Input"],
            CounterIncrements -> "CellCount"
        ],
        Cell[StyleData["Notebook"],
            TaggingRules -> "TotalCells" -> Dynamic[Length[Cells[CellStyle -> "Input"]]]
        ],
        Cell[StyleData["Section"], 
            CellDingbat -> Cell @ BoxData @ DynamicBox[
                RowBox[{
                    "(",
                    ToBoxes[
                        AbsoluteCurrentValue[ParentCell[EvaluationCell[]], {TaggingRules, "NextSection"}] - 
                        AbsoluteCurrentValue[ParentCell[EvaluationCell[]], {TaggingRules, "ThisSection"}]
                    ],
                    ")"
                }]
            ], 
            TaggingRules -> {
                "NextSection" -> Dynamic @ Replace[
                    NextCell[CellStyle -> "Section"], 
                    {
                    None :> CurrentValue[EvaluationNotebook[], {TaggingRules, "TotalCells"}], 
                    o_ :> CurrentValue[o, {"CounterValue", "CellCount"}]
                    }
                ],
                "ThisSection" -> Dynamic[CurrentValue[EvaluationCell[], {"CounterValue", "CellCount"}]]}], 
        }, 
        StyleDefinitions -> "PrivateStylesheetFormatting.nb"
    ]
]

Note that all the dynamic content might cause the notebook to be laggy.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.