Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[ENH] Minigallery can take arbitrary files/glob patterns as input #1226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 31, 2024

Conversation

story645
Copy link
Contributor

@story645 story645 commented Nov 10, 2023

Closes #1029

  • still have to finish up tests and docs, but wanted some feedback if this was in the right direction.

  • If so, I'm also wondering if I could strip the thumbnail parent div out of the backref files so that I could do it in the loop.

  • get .py files in .rst folders working - seems to work by default and issue was sorting

  • file sort order

@larsoner
Copy link
Contributor

If so, I'm also wondering if I could strip the thumbnail parent div out of the backref files so that I could do it in the loop.

Not sure if this will break anything or not. But you could do it and we could check to see if things still render properly.

And if it makes sense to add a ... arg that will look in the folder for a readme that defines the sort order?

I'm not sure how it would work to use RST to define the order, but agree it makes sense to define it somewhere somehow.

A solution that would be more consistent with other order setting mechanics would be to provide a sphinx_gallery_conf["minigallery_sort_order"] that's a callable that takes whatever it needs to take (probably the current source file and list of examples or something?) and returns the sorted order or so.

@story645
Copy link
Contributor Author

story645 commented Nov 13, 2023

I'm not sure how it would work to use RST to define the order, but agree it makes sense to define it somewhere somehow.

Was thinking about this 'cause #1068 but realizing the answer to both this is probably a FromFileOrder type object. ETA or like Tim's suggestion, expand the matplotlib ordering object to also look in files.

@story645
Copy link
Contributor Author

story645 commented Nov 16, 2023

b/c I have gone down way too deep an html/xml rabbit hole, does it matter if the heading is before or in the thumbnail parent div? my bias is for in b/c then it stays together as part of the DOM

ETA: also main reason for completely rewriting the minigallery test was to get a better sense of expected behavior.

@lucyleeow
Copy link
Contributor

lucyleeow commented Nov 16, 2023

I have gone down way too deep an html/xml rabbit hole

I have nothing to contribute here but I just wanted to thank you for your hard work.

Also the CIs are failing because scipy docs site certificate has expired scipy/docs.scipy.org#80

@larsoner
Copy link
Contributor

does it matter if the heading is before or in the thumbnail parent div? my bias is for in b/c then it stays together as part of the DOM

I am not really sure but if I had to guess I would say no it shouldn't matter, so feel free to try moving it

@story645
Copy link
Contributor Author

. so feel free to try moving it

Moved it inside in this PR and the build looks the same to me.

@story645
Copy link
Contributor Author

story645 commented Nov 17, 2023

that's a callable that takes whatever it needs to take (probably the current source file and list of examples or something?) and returns the sorted order or so.

I think a standalone/separate PR would be to make something like a FileOrder(ExplicitOrder) object that can be configured with the file it should look for the ordering, and that returns a callable that works like ExplicitOrder and that for this PR I should just make sure that a [minigallery] ordering config of some sort will work.

Also test failures are I think cause I moved the title into the div/changed the backreferences file, so I'll sort that out probably in the coming week or so.

@larsoner
Copy link
Contributor

I think a standalone/separate PR would be to make something like a FileOrder(ExplicitOrder) object that can be configured with the file it should look for the ordering

Thinking about this more... I'm not sure we can/should implement this at the SG end, at least to start. You could already implement and use this in matplotlib because you can define your own sortkey if you want. For example following this code:

https://sphinx-gallery.github.io/stable/_modules/sphinx_gallery/sorting.html#ExampleTitleSortKey

I'd expect something like the following, where the ... is whatever you need to do to parse the RST in whatever way matplotlib wants to specify the information:

class RSTSortKey:

    def __init__(self, src_dir):
        self.src_dir = src_dir
        readme_txt = Path(src_dir) / "README.rst").read_text("utf-8")
        self.fname_list_orderered = ...  # something you pull from the readme

    def __call__(self, filename):
        return self.fname_list_ordered.index(filename)

@larsoner
Copy link
Contributor

... in other words, I think the hard/interesting work here is in the ... above, and that's going to be a bit specific to how matplotlib does things. But assuming that works, it would be great to link from the SG config docs to the matplotlib code showing how the SortKey-based framework is general enough to support this use case!

@story645
Copy link
Contributor Author

story645 commented Nov 23, 2023

This is amazing and also probably a sign I messed up divs. ETA: confirmed, this is what happens if I try to put the heading inside the thumbnail div 😅

image

@story645 story645 force-pushed the minigallery branch 11 times, most recently from 0e1897e to 4ba2a06 Compare November 24, 2023 08:45
@story645 story645 marked this pull request as ready for review November 24, 2023 08:59
@lucyleeow
Copy link
Contributor

lucyleeow commented Jan 31, 2024

So pushed into a separate commit in case you want to reject, because I understand why you'd want to frontload the FunctionSortKey but I pulled the repr discussion up 'cause I thought the section flow was jumpy otherwise.

That's fine, I've used this ordering.

Some minor changes:

  • I've just used .name to get the filename instead of the full path (it's not pretty but we were manipulating the sort elements anyway so 🤷) - did not find a way to test this directly but I have amended MockSort so it will fail if not just the filename
  • I've allowed None as a minigallery_sort_order input - could not think of way to test this directly, though i noticed we don't test this for subsection_order either
  • I don't think the doc config minigallery_sort_order in the SG docs was working (as we were passing the full path before) and I didn't think it was necessary. Also now something fails if minigallery_sort_order does not allow None
  • Doc amendments. I have realised that you cannot use FunctionSortKey for within_subsection_order config as they get instantiated with the source dir

@lucyleeow lucyleeow enabled auto-merge (squash) January 31, 2024 05:19
@lucyleeow
Copy link
Contributor

Thanks @story645 for all your work. Just made minor fixes to save you time.

sortkey = config.sphinx_gallery_conf["minigallery_sort_order"]
for obj, path in sorted(
set(file_paths),
key=((lambda x: sortkey(str(x[-1].name))) if sortkey else None),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think you want more than just the name if you want to keep files in a subfolder together.

@lucyleeow lucyleeow merged commit 31e036c into sphinx-gallery:master Jan 31, 2024
@story645
Copy link
Contributor Author

I've just used .name to get the filename instead of the full path (it's not pretty but we were manipulating the sort elements anyway so 🤷) - did not find a way to test this directly but I have amended MockSort so it will fail if not just the filename

Mentioned this in a review, but this won't let you keep files in a subfolder together and will collapse two files of the same name in different subfolders & I think those are some of the primary reasons I'd want to sort.

@lucyleeow
Copy link
Contributor

lucyleeow commented Jan 31, 2024

Ah sorry I missed that. What about the making the paths relative to src_dir ?

We could probably do that here:

            elif paths := Path(src_dir).glob(obj):
                file_paths.extend([(obj, p) for p in paths])

?

Maybe we could add a test to capture this? And update the documentation so people know what we're sorting on.

Let me know if you don't want to work on it.

@story645
Copy link
Contributor Author

story645 commented Jan 31, 2024

Let me know if you don't want to work on it.

I was actually gonna open up a PR to put back sorting on the full path.

What making the making the paths relative to src_dir?

    elif paths := Path(src_dir).glob(obj):
            file_paths.extend([(obj, p) for p in paths])

Path(src_dir).glob(obj) returns a Path relative to source dir, while os.path.abspath and .absolute get rid of it, and I think maybe the solution is put that in the sortkey -> it can't be done here b/c the source parsing files all want the relative to src_dir path far as I can tell. The issue is that the examples folders are not subfolders of src_dir so trying to make them absolute loses the relative position to src_dir.

@lucyleeow
Copy link
Contributor

That's fine. We can do it in the sortkey, maybe adding a parent ? I think we only ever go 1 folder deep.

@story645 story645 deleted the minigallery branch January 31, 2024 05:44
@story645
Copy link
Contributor Author

I think we only ever go 1 folder deep.

Ehh, Matplotlib does some wonky nested nonsense so I'd rather be as general as possible.

@lucyleeow
Copy link
Contributor

Sure I'm okay with it the previous status, but it should be documented so people know what we're sorting on (and that it's not just the filename). And tested if possible...

@lucyleeow
Copy link
Contributor

Actually, the filepath input arg to the directive would be okay? Since they have to give the filepath relative to conf.py so subfolder structure would be retained?

@story645
Copy link
Contributor Author

Actually, the filepath input arg to the directive would be okay?

Don't think so b/c it can also be a glob expression ../*/*.py

@lucyleeow
Copy link
Contributor

Oh yeah good point.

I realise now why I thought it should be the filename, the example we give is along the lines of x.startswith('plot'). That would be trickier with the full path, they would have split the path but that's unavoidable if we want the subdir in there.

@lucyleeow
Copy link
Contributor

Ehh, Matplotlib does some wonky nested nonsense so I'd rather be as general as possible.

I meant that I think sphinx gallery only looks 1 level down for subdirs, though matplotlib may do funny things to get around this?

@story645
Copy link
Contributor Author

story645 commented Jan 31, 2024

I meant that I think sphinx gallery only looks 1 level down for subdirs, though matplotlib may do funny things to get around this?

Hmm, I'm probably wrong then and we only have one level of subdirs? Where https://github.com/matplotlib/matplotlib/tree/main/galleries is our tree...hmm,

they would have split the path but that's unavoidable if we want the subdir in there.

os.path.basename(x).startswith('plot')

I think a worthwhile followup PR is for the sortkey callables to take Path or string, but is out of scope here I think.

clrpackages referenced this pull request in clearlinux-pkgs/pypi-sphinx_gallery Apr 30, 2024
… to version 0.16.0

v0.16.0
-------
Sphinx 7.3.0 and above changed caching and serialization checks. Now instead of passing
instantiated classes like ``ResetArgv()``, classes like ``FileNameSortKey``, or
callables like ``notebook_modification_function`` in  ``sphinx_gallery_conf``,
you should pass fully qualified name strings to classes or callables. If you change
to using name strings, you can simply use a function as the use of classes to ensure
a stable ``__repr__`` would be redundant.

See :ref:`importing_callables` for details.

**Implemented enhancements:**

-  ENH: Allow plain list as subsection_order and support a wildcard `#1295 <https://github.com/sphinx-gallery/sphinx-gallery/pull/1295>`__ (`timhoffm <https://github.com/timhoffm>`__)
-  [ENH] Minigallery can take arbitrary files/glob patterns as input `#1226 <https://github.com/sphinx-gallery/sphinx-gallery/pull/1226>`__ (`story645 <https://github.com/story645>`__)

(NEWS truncated at 15 lines)
Comment on lines +139 to +142
raise ExtensionError(
f"Error in gallery lookup: input={obj}, matches={dirs}, "
f"examples={config.sphinx_gallery_conf['examples_dirs']}"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@story645 I stumbled on this error accidentally but I don't fully follow what situation this is meant to catch?

I managed to contrive a case where I added a file to a path not in examples_dir to a minigallery directive. In that case there were no matches and the error message didn't really make sense.

I assume it is meant to catch cases when dirs>1? So maybe a sub-gallery directory is named the same as a examples gallery?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more informative error message would be great. There is no test for this but depending on what this is mean to catch, maybe it would be too difficult to write a test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @larsoner just in case you remember...? 😬

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea 😞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create mini-gallery with an arbitrary list of gallery items
3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.