🏠 back to Observable

How to get a cell’s name?

How can I get a cell’s name?

E.g. to create some generic documentation, I’d like call a function with a cell reference as argument and then generate some md that includes the cell’s name.

hiThere = ({width: 10, height: 10, description: "Hello world."})

function describe(cell) {
  return md`Cell *${cell.constructor.name}*’s description is “${cell.description  }”`;
}

describe(hiThere)

Cell Object’s description is “Hello world.”

1 Like

Martien,

You can probably import and inspect notebook nodes (cells) via oficial observable runtime js library that is used for embeds, etc. (see: https://beta.observablehq.com/@jashkenas/downloading-and-embedding-notebooks):

Also, this is not officially supported, but recently I put together notebooks.js notebook that shows you how to use observable api directly for getting user bio, notebooks info, and notebook cells. see Getting Notebook Info and #notebookNodes section here:

Every notebook on observable is stored/returned in this json format:

Even though nodes don’t break cell names and code blocks into separate properties, I think you can easily parse out named cells names from the code node value by index of = and ( for functions :slight_smile:

Do you intend to have this notebook documentation system outside of the hosted notebook itself? If so that might help.

I am curious how you auto-generate cell’s description. Are you thinking along the lines of creating spec. js for each notebook you create?

Thanks Taras! Will look into it.

1 Like

I can add a short snippet to my noteboosk.js for namedCells and functions extract from notebook nodes value.

still wondering how you intend to use it? outside of observable as a custom js script similar to how we do unit tests with spec.js but for docs?

very good question and idea! I never thought of notebook cell docs. def. worth considering adding to some form of observable runtime in the future.

Initial use is very simple. Instead of saying:

howToImport(ccbysablock, "ccbysablock")

I want to say:

howToImport(ccbysablock)

Where ccbysablock is an object. howToImport() then simply outputs the string:

import {ccbysablock} from "@martien/creative-commons-logos" (108:36 (3:1))

ccbysablock look like this:

 ccbysablock = ({
   width: 108,
   height: 36,
   xml: `…`
 })

So it gets the object’s name and its dimensions from the object itself.

This makes it easier to have code self-describe. Meta-doc, if you will.

Have a look at Martien » Creative Commons Logos for how I now use it.

so you just want named cells and functions with params and default values. can be easily done.

not sure if I’d call it a proper js generated doc, but probably could be a good start as a template to doc named cells, objects, functions and params.

Even less than that. I just want to pass an object to a function, where that function can get the name of the object passed. That’s it.

Maybe the subject is confusing and should have said “How to get an object’s name?”

you are trying to solution this and it’s confusing.

what is it you’d like to accomplish with that notebook?

are you creating logos for others to export logo svg with proper sizing to be used elsewhere?

or you are planning to add creative coomons logos in diff. sizes for others to import from your notebook?

Sorry to be unclear and confusing. Forget about the logos.

Maybe it helps to say what I do not want:

I do not want to type in an object’s name twice, once as the object, and once as its string.

If you look at:

function howToImport(logo, logoName) {
  let d = gcd(logo.width, logo.height);
  return md`\`import {${logoName}} from "@martien/creative-commons-logos"
(${logo.width}:${logo.height} (${logo.width / d}:${logo.height / d}))\``;
}

I now call:

howToImport(ccbysastrip, "ccbysastrip")

I want to call:

howToImport(ccbysastrip)

and have howToImport figure out the name of the parameter it is called with.

Does this make things clearer for you?

:slight_smile:

  1. I would suggest you name your creative commons logo cells for deep linking:

mylogo = banner(ccbysastrip)

then you can link to them directly:

  1. then I would recommend you add save as png or svg below each logo:

add this to your notebook:

import {rasterize, serialize} from ‘@mbostock/saving-svg’

then this code snippet below each logo svg:

html`
${DOM.download(await rasterize(mylogo), 'logo.png', "Download as PNG")}
${DOM.download(await serialize(mylogo), `logo.svg`, "Download as SVG")}
`
  1. then others can import your logos by name too from your logos notebook. try:
import {mylogo} from '[yournotebook]'

all bases covered?

Sorry, that is not what I need. I don’t need png or svg to download. I’m just a guy who exhausts himself in laziness and want Greyhound to do the driving. If I type in the name of an object, there must be some way to get that name (as a string), right?

Never mind. It works for now, so yes, we’re done.

Thanks very much for your effort and brain cycles.

How about the following? I hacked this together from this SO answer which explains how it works:

function howToImport2(logoDict) {
  function getVariableName(unknownVariable) {
    return Object.keys(unknownVariable)[0];
  };
  const logo = logoDict[getVariableName(logoDict)];
  let d = gcd(logo.width, logo.height);
  return md`\`import {${getVariableName(logoDict)}} from "@martien/creative-commons-logos"
(${logo.width}:${logo.height} (${logo.width / d}:${logo.height / d}))\``;
}

To use howtoimport2, note that you have to do the slightly odd thing of wrapping the argument in curly braces like this:

howToImport2({ccbysablock})
2 Likes

Wonderful! Works like a charm and exactly what I need.

Thanks @bgchen