```python
def is_md_cell(c): return c.cell_type == 'markdown'
md_cells = L(nb.cells).filter(is_md_cell)
md_cells
```
(#39) [{'cell_type': 'markdown', 'id': 'b8ca3733', 'metadata': {}, 'source': '# A Better Notebook Index Page', 'idx_': 0},{'cell_type': 'markdown', 'id': '0adccd3d', 'metadata': {}, 'source': "I've made good progress on creating a notebook every day. Now I have so many notebooks that my index page needs an overhaul, including:\n\n* Dates with datetime\n* Cards with execnb to grab notebook titles\n* The cache decorator to make that fast\n* Subtle CSS tweaks to increase information density", 'idx_': 1},{'cell_type': 'markdown', 'id': '9f9ab0bb', 'metadata': {}, 'source': '## List Live Posts', 'idx_': 3},{'cell_type': 'markdown', 'id': '8e35e71e', 'metadata': {}, 'source': 'According to this, I have 34 notebooks in `arg-blog-fasthtml/nbs`, which matches the 34 cards on audrey.feldroy.com.', 'idx_': 5},{'cell_type': 'markdown', 'id': '506c2763', 'metadata': {}, 'source': '## Pathlib, User Directory, and PosixPath', 'idx_': 6},{'cell_type': 'markdown', 'id': 'c57a8f71', 'metadata': {}, 'source': 'To specify the path in terms of my home directory `~`, I use `PosixPath`.', 'idx_': 8},{'cell_type': 'markdown', 'id': 'f8f7b5f2', 'metadata': {}, 'source': 'Here I expand `~` into `/Users/arg/`, list files that end in .ipynb, and convert the generator object into a readable list with a fastcore `L` list.', 'idx_': 10},{'cell_type': 'markdown', 'id': '8f1183a3', 'metadata': {}, 'source': '## Display the Notebooks List Nicely', 'idx_': 11},{'cell_type': 'markdown', 'id': '33cf8a98', 'metadata': {}, 'source': 'If we just print the filenames, we can see my current approach of naming them with the date and TitleCase title.', 'idx_': 13},{'cell_type': 'markdown', 'id': '96344324', 'metadata': {}, 'source': '## New Approach', 'idx_': 14},{'cell_type': 'markdown', 'id': '4bd7dc56', 'metadata': {}, 'source': 'Doing this has given me insight about how to improve my site:\n\n* Keep naming files as before\n* Now for the index page, get the titles from the notebooks instead of the filenames', 'idx_': 15},{'cell_type': 'markdown', 'id': 'e63668fc', 'metadata': {}, 'source': 'When there were just a few notebooks, these cards were great. Now I want a more information-dense layout with tighter cards, and with titles containing proper punctuation coming from the notebooks themselves.', 'idx_': 16},{'cell_type': 'markdown', 'id': '7daf2fca', 'metadata': {}, 'source': '## Revisit Date Parsing', 'idx_': 17},{'cell_type': 'markdown', 'id': 'd0204966', 'metadata': {}, 'source': "I'm currently getting dates from ISO 8601-prefixed filenames with this not-great code that I hacked together quickly:", 'idx_': 18},{'cell_type': 'markdown', 'id': '5e7a96cd', 'metadata': {}, 'source': "I talked with Claude 3.5 Sonnet about it. It generated code that looked awesome at first but wasn't my favorite when I experimented with it carefully. But something good resulted: out of that I learned about `datetime.fromisoformat` and looked it up in the [Python datetime docs](https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat).", 'idx_': 20},{'cell_type': 'markdown', 'id': '4bdadc6d', 'metadata': {}, 'source': "It's actually nice to have `datetime` objects here because I can get the parts like:", 'idx_': 22},{'cell_type': 'markdown', 'id': '5956ab70', 'metadata': {}, 'source': 'And print them with f-strings:', 'idx_': 24},{'cell_type': 'markdown', 'id': '41130f57', 'metadata': {}, 'source': "I like that combination of readability and abbreviations. I'll try it and see if I still like it later.", 'idx_': 26},{'cell_type': 'markdown', 'id': '3f2adffb', 'metadata': {}, 'source': '## Iterate on ISO 8601 Date Parsing', 'idx_': 27},{'cell_type': 'markdown', 'id': '0a9e4008', 'metadata': {}, 'source': 'My improved function:', 'idx_': 28}...]