diff --git a/doc/conf.py b/doc/conf.py index ab1b632203f1d..e94021069a23a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -64,7 +64,6 @@ "sphinx_remove_toctrees", "sphinx_design", # See sphinxext/ - "add_toctree_functions", "allow_nan_estimators", "doi_role", "move_gallery_links", @@ -315,9 +314,7 @@ # Additional templates that should be rendered to pages, maps page names to # template names. -# TODO: change to html_additional_pages = {"index": "index.html"} so that our landing -# page template can override the one generated from index.rst -html_additional_pages = {} +html_additional_pages = {"index": "index.html"} # Additional JS files html_js_files = ["scripts/details-permalink.js"] @@ -340,7 +337,9 @@ def add_js_css_files(app, pagename, templatename, context, doctree): should be used for the ones that are used by multiple pages. All page-specific JS and CSS files should be added here instead. """ - if pagename == "install": + if pagename == "index": + app.add_css_file("styles/index.css") + elif pagename == "install": app.add_css_file("styles/install.css") @@ -740,7 +739,7 @@ def filter_search_index(app, exception): f.write(searchindex_text) -def generate_min_dependency_table(app): +def generate_min_dependency_table(): """Generate min dependency table for docs.""" from sklearn._min_dependencies import dependent_packages @@ -786,11 +785,11 @@ def generate_min_dependency_table(app): output.write("\n") output = output.getvalue() - with (Path(".") / "min_dependency_table.rst").open("w") as f: + with (Path(".") / "min_dependency_table.rst").open("w", encoding="utf-8") as f: f.write(output) -def generate_min_dependency_substitutions(app): +def generate_min_dependency_substitutions(): """Generate min dependency substitutions for docs.""" from sklearn._min_dependencies import dependent_packages @@ -803,7 +802,55 @@ def generate_min_dependency_substitutions(app): output = output.getvalue() - with (Path(".") / "min_dependency_substitutions.rst").open("w") as f: + with (Path(".") / "min_dependency_substitutions.rst").open( + "w", encoding="utf-8" + ) as f: + f.write(output) + + +def generate_index_rst(): + """Generate index.rst. + + The reason for generating this file at build time is to allow specifying the + development link as a variable. + https://github.com/scikit-learn/scikit-learn/pull/22550 + """ + development_link = ( + "developers/index" + if parsed_version.is_devrelease + else "https://scikit-learn.org/dev/developers/index.html" + ) + + output = f""" +.. title:: Index + +.. Define the overall structure, that affects the prev-next buttons and the order + of the sections in the top navbar. + +.. toctree:: + :hidden: + :maxdepth: 2 + + Install + user_guide + API + auto_examples/index + Community + getting_started + Tutorials + whats_new + Glossary + Development <{development_link}> + FAQ + support + related_projects + roadmap + Governance + about + Other Versions and Download +""" + + with (Path(".") / "index.rst").open("w", encoding="utf-8") as f: f.write(output) @@ -822,8 +869,6 @@ def setup(app): # do not run the examples when using linkcheck by using a small priority # (default priority is 500 and sphinx-gallery using builder-inited event too) app.connect("builder-inited", disable_plot_gallery_for_linkcheck, priority=50) - app.connect("builder-inited", generate_min_dependency_table) - app.connect("builder-inited", generate_min_dependency_substitutions) # triggered just before the HTML for an individual page is created app.connect("html-page-context", add_js_css_files) @@ -954,3 +999,8 @@ def setup(app): linkcheck_request_headers = { "https://github.com/": {"Authorization": f"token {github_token}"}, } + +# Write the pages prior to any sphinx event +generate_index_rst() +generate_min_dependency_table() +generate_min_dependency_substitutions() diff --git a/doc/index.rst b/doc/index.rst deleted file mode 100644 index afe15ae4f044f..0000000000000 --- a/doc/index.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. title:: Index - -.. Define the overall structure, that affects the prev-next buttons and the order - of the sections in the top navbar. - -.. toctree:: - :hidden: - :maxdepth: 2 - - Install - user_guide - API - auto_examples/index - Community - getting_started - Tutorials - whats_new - Glossary - Development - FAQ - support - related_projects - roadmap - Governance - about - Other Versions and Download diff --git a/doc/scss/colors.scss b/doc/scss/colors.scss index 767f9ce435ae9..bbc6aa6c2a3d6 100644 --- a/doc/scss/colors.scss +++ b/doc/scss/colors.scss @@ -1,6 +1,9 @@ /** * This is the style sheet for customized colors of scikit-learn. * Tints and shades are generated by https://colorkit.co/color-shades-generator/ + * + * This file is compiled into styles/colors.css by sphinxcontrib.sass, see: + * https://sass-lang.com/guide/ */ :root { diff --git a/doc/scss/custom.scss b/doc/scss/custom.scss index 1808a8048b73f..495ab69455206 100644 --- a/doc/scss/custom.scss +++ b/doc/scss/custom.scss @@ -1,6 +1,9 @@ /** * This is a general styling sheet. * It should be used for customizations that affect multiple pages. + * + * This file is compiled into styles/custom.css by sphinxcontrib.sass, see: + * https://sass-lang.com/guide/ */ /* Global */ diff --git a/doc/scss/index.scss b/doc/scss/index.scss new file mode 100644 index 0000000000000..4e3f371f236d4 --- /dev/null +++ b/doc/scss/index.scss @@ -0,0 +1,175 @@ +/** + * Styling sheet for the scikit-learn landing page. This should be loaded only for the + * landing page. + * + * This file is compiled into styles/index.css by sphinxcontrib.sass, see: + * https://sass-lang.com/guide/ + */ + +/* Theme-aware colors for the landing page */ + +html { + &[data-theme="light"] { + --sk-landing-bg-1: var(--sk-cyan-shades-3); + --sk-landing-bg-2: var(--sk-cyan); + --sk-landing-bg-3: var(--sk-orange-tint-8); + --sk-landing-bg-4: var(--sk-orange-tint-3); + } + + &[data-theme="dark"] { + --sk-landing-bg-1: var(--sk-cyan-shades-5); + --sk-landing-bg-2: var(--sk-cyan-shades-2); + --sk-landing-bg-3: var(--sk-orange-tint-4); + --sk-landing-bg-4: var(--sk-orange-tint-1); + } +} + +/* General */ + +div.sk-landing-container { + max-width: 1400px; +} + +/* Top bar */ + +div.sk-landing-top-bar { + background-image: linear-gradient( + 160deg, + var(--sk-landing-bg-1) 0%, + var(--sk-landing-bg-2) 17%, + var(--sk-landing-bg-3) 59%, + var(--sk-landing-bg-4) 100% + ); + + .sk-landing-header, + .sk-landing-subheader { + color: white; + text-shadow: 0px 0px 8px var(--sk-landing-bg-1); + } + + .sk-landing-header { + font-size: 3.2rem; + margin-bottom: 0.5rem; + } + + .sk-landing-subheader { + letter-spacing: 0.17rem; + margin-top: 0; + font-weight: 500; + } + + a.sk-btn-orange { + font-size: 1.1rem; + font-weight: 500; + } + + ul.sk-landing-header-body { + margin-top: auto; + margin-bottom: auto; + font-size: 1.2rem; + font-weight: 500; + color: black; + } +} + +/* Body */ + +div.sk-landing-body { + div.card { + background-color: var(--pst-color-background); + border-color: var(--pst-color-border); + } + + .sk-px-xl-4 { + @media screen and (min-width: 1200px) { + padding-left: 1.3rem !important; + padding-right: 1.3rem !important; + } + } + + .card-body { + p { + margin-bottom: 0.8rem; + } + + .sk-card-title { + font-weight: 700; + margin: 0 0 1rem 0; + } + } + + .sk-card-img-container { + display: flex; + justify-content: center; + align-items: end; + margin-bottom: 1rem; + + img { + max-width: unset; + height: 15rem; + } + } +} + +/* More info */ + +div.sk-landing-more-info { + font-size: 0.96rem; + background-color: var(--pst-color-surface); + + .sk-landing-call-header { + font-weight: 700; + margin-top: 0; + + html[data-theme="light"] & { + color: var(--sk-orange-shades-1); + } + + html[data-theme="dark"] & { + color: var(--sk-orange); + } + } + + ul.sk-landing-call-list > li { + margin-bottom: 0.25rem; + } + + .sk-who-uses-carousel { + min-height: 200px; + + .carousel-item img { + max-height: 100px; + max-width: 50%; + margin: 0.5rem; + } + } + + .sk-more-testimonials { + text-align: right !important; + } +} + +/* Footer */ + +div.sk-landing-footer { + a.sk-footer-funding-link { + text-decoration: none; + + p.sk-footer-funding-text { + color: var(--pst-color-link); + + &:hover { + color: var(--pst-color-secondary); + } + } + + div.sk-footer-funding-logos > img { + max-height: 40px; + max-width: 85px; + margin: 0 8px 8px 8px; + padding: 5px; + border-radius: 3px; + background-color: white; + } + } +} diff --git a/doc/scss/install.scss b/doc/scss/install.scss index 7db91d1a6299a..965b3d589e86d 100644 --- a/doc/scss/install.scss +++ b/doc/scss/install.scss @@ -1,6 +1,9 @@ /** * Styling for the installation page, including overriding some default styling of * sphinx-design. This style sheet should be included only for the install page. + * + * This file is compiled into styles/install.css by sphinxcontrib.sass, see: + * https://sass-lang.com/guide/ */ .install-instructions .sd-tab-set { diff --git a/doc/sphinxext/add_toctree_functions.py b/doc/sphinxext/add_toctree_functions.py deleted file mode 100644 index 4459ab971f4c4..0000000000000 --- a/doc/sphinxext/add_toctree_functions.py +++ /dev/null @@ -1,160 +0,0 @@ -"""Inspired by https://github.com/pandas-dev/pydata-sphinx-theme - -BSD 3-Clause License - -Copyright (c) 2018, pandas -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -import docutils - - -def add_toctree_functions(app, pagename, templatename, context, doctree): - """Add functions so Jinja templates can add toctree objects. - - This converts the docutils nodes into a nested dictionary that Jinja can - use in our templating. - """ - from sphinx.environment.adapters.toctree import TocTree - - def get_nav_object(maxdepth=None, collapse=True, numbered=False, **kwargs): - """Return a list of nav links that can be accessed from Jinja. - - Parameters - ---------- - maxdepth: int - How many layers of TocTree will be returned - collapse: bool - Whether to only include sub-pages of the currently-active page, - instead of sub-pages of all top-level pages of the site. - numbered: bool - Whether to add section number to title - kwargs: key/val pairs - Passed to the `TocTree.get_toctree_for` Sphinx method - """ - # The TocTree will contain the full site TocTree including sub-pages. - # "collapse=True" collapses sub-pages of non-active TOC pages. - # maxdepth controls how many TOC levels are returned - toctree = TocTree(app.env).get_toctree_for( - pagename, app.builder, collapse=collapse, maxdepth=maxdepth, **kwargs - ) - # If no toctree is defined (AKA a single-page site), skip this - if toctree is None: - return [] - - # toctree has this structure - # - # - # - # - # `list_item`s are the actual TOC links and are the only thing we want - toc_items = [ - item - for child in toctree.children - for item in child - if isinstance(item, docutils.nodes.list_item) - ] - - # Now convert our docutils nodes into dicts that Jinja can use - nav = [ - docutils_node_to_jinja(child, only_pages=True, numbered=numbered) - for child in toc_items - ] - - return nav - - context["get_nav_object"] = get_nav_object - - -def docutils_node_to_jinja(list_item, only_pages=False, numbered=False): - """Convert a docutils node to a structure that can be read by Jinja. - - Parameters - ---------- - list_item : docutils list_item node - A parent item, potentially with children, corresponding to the level - of a TocTree. - only_pages : bool - Only include items for full pages in the output dictionary. Exclude - anchor links (TOC items with a URL that starts with #) - numbered: bool - Whether to add section number to title - - Returns - ------- - nav : dict - The TocTree, converted into a dictionary with key/values that work - within Jinja. - """ - if not list_item.children: - return None - - # We assume this structure of a list item: - # - # - # <-- the thing we want - reference = list_item.children[0].children[0] - title = reference.astext() - url = reference.attributes["refuri"] - active = "current" in list_item.attributes["classes"] - - secnumber = reference.attributes.get("secnumber", None) - if numbered and secnumber is not None: - secnumber = ".".join(str(n) for n in secnumber) - title = f"{secnumber}. {title}" - - # If we've got an anchor link, skip it if we wish - if only_pages and "#" in url: - return None - - # Converting the docutils attributes into jinja-friendly objects - nav = {} - nav["title"] = title - nav["url"] = url - nav["active"] = active - - # Recursively convert children as well - # If there are sub-pages for this list_item, there should be two children: - # a paragraph, and a bullet_list. - nav["children"] = [] - if len(list_item.children) > 1: - # The `.children` of the bullet_list has the nodes of the sub-pages. - subpage_list = list_item.children[1].children - for sub_page in subpage_list: - child_nav = docutils_node_to_jinja( - sub_page, only_pages=only_pages, numbered=numbered - ) - if child_nav is not None: - nav["children"].append(child_nav) - return nav - - -def setup(app): - app.connect("html-page-context", add_toctree_functions) - - return {"parallel_read_safe": True, "parallel_write_safe": True} diff --git a/doc/templates/index.html b/doc/templates/index.html index ebe51074994d4..913c9e2a40122 100644 --- a/doc/templates/index.html +++ b/doc/templates/index.html @@ -1,25 +1,27 @@ {% extends "layout.html" %} {% set title = 'scikit-learn: machine learning in Python' %} -{% if theme_link_to_live_contributing_page|tobool %} +{% if is_devrelease|tobool %} + {%- set contributing_link = pathto("developers/contributing") %} + {%- set contributing_attrs = "" %} +{%- else %} {%- set contributing_link = "https://scikit-learn.org/dev/developers/contributing.html" %} {%- set contributing_attrs = 'target="_blank" rel="noopener noreferrer"' %} -{%- else %} - {%- set contributing_link = pathto('developers/contributing') %} - {%- set contributing_attrs = '' %} {%- endif %} +{%- import "static/webpack-macros.html" as _webpack with context %} -{% block content %} -
+{% block docs_navbar %} +{{ super() }} + +
-

scikit-learn

-

Machine Learning in Python

- Getting Started - Release Highlights for {{ release_highlights_version }} - GitHub +

scikit-learn

+

Machine Learning in Python

+ Getting Started + Release Highlights for {{ release_highlights_version }}
    @@ -33,236 +35,276 @@

    Machine Learning in

-
+{% endblock docs_navbar %} + +{% block docs_main %} + +
+
-
+
-

Classification

-

Identifying which category an object belongs to.

-

Applications: Spam detection, image recognition.
- Algorithms: - Gradient boosting, - nearest neighbors, - random forest, - logistic regression, - and more...

+

+ Classification +

+

Identifying which category an object belongs to.

+

+ Applications: Spam detection, image recognition.
+ Algorithms: + Gradient boosting, + nearest neighbors, + random forest, + logistic regression, + and more... +

-
+
-
+
-

Regression

-

Predicting a continuous-valued attribute associated with an object.

-

Applications: Drug response, Stock prices.
- Algorithms: - Gradient boosting, - nearest neighbors, - random forest, - ridge, - and more...

+

+ Regression +

+

Predicting a continuous-valued attribute associated with an object.

+

+ Applications: Drug response, stock prices.
+ Algorithms: + Gradient boosting, + nearest neighbors, + random forest, + ridge, + and more... +

-
+
-
+
-

Clustering

-

Automatic grouping of similar objects into sets.

-

Applications: Customer segmentation, Grouping experiment outcomes
- Algorithms: - k-Means, - HDBSCAN, - hierarchical - clustering, - and more...

+

+ Clustering +

+

Automatic grouping of similar objects into sets.

+

+ Applications: Customer segmentation, grouping experiment outcomes.
+ Algorithms: + k-Means, + HDBSCAN, + hierarchical clustering, + and more... +

-
+
-
+
-

Dimensionality reduction

-

Reducing the number of random variables to consider.

-

Applications: Visualization, Increased efficiency
- Algorithms: - PCA, - feature selection, - non-negative matrix factorization, - and more...

+

+ Dimensionality reduction +

+

Reducing the number of random variables to consider.

+

+ Applications: Visualization, increased efficiency.
+ Algorithms: + PCA, + feature selection, + non-negative matrix factorization, + and more... +

-
+
-
+
-

Model selection

-

Comparing, validating and choosing parameters and models.

-

Applications: Improved accuracy via parameter tuning
- Algorithms: - grid search, - cross validation, - metrics, - and more...

+

+ Model selection +

+

Comparing, validating and choosing parameters and models.

+

+ Applications: Improved accuracy via parameter tuning.
+ Algorithms: + Grid search, + cross validation, + metrics, + and more... +

-
+
-
+
-

Preprocessing

-

Feature extraction and normalization.

-

Applications: Transforming input data such as text for use with machine learning algorithms.
- Algorithms: - preprocessing, - feature extraction, - and more...

+

+ Preprocessing +

+

Feature extraction and normalization.

+

+ Applications: Transforming input data such as text for use with machine learning algorithms.
+ Algorithms: + Preprocessing, + feature extraction, + and more... +

-
-
-
+{% endblock docs_main %} + +{% block footer %} + +
+
+

News

    -
  • On-going development: - scikit-learn 1.5 (Changelog) -
  • -
  • February 2024. scikit-learn 1.4.1 is available for download (Changelog). -
  • -
  • January 2024. scikit-learn 1.4.0 is available for download (Changelog). -
  • -
  • October 2023. scikit-learn 1.3.2 is available for download (Changelog). -
  • -
  • September 2023. scikit-learn 1.3.1 is available for download (Changelog). -
  • -
  • June 2023. scikit-learn 1.3.0 is available for download (Changelog). -
  • -
  • All releases: - What's new (Changelog) -
  • +
  • On-going development: scikit-learn 1.5 (Changelog).
  • +
  • February 2024. scikit-learn 1.4.1 is available for download (Changelog).
  • +
  • January 2024. scikit-learn 1.4.0 is available for download (Changelog).
  • +
  • October 2023. scikit-learn 1.3.2 is available for download (Changelog).
  • +
  • September 2023. scikit-learn 1.3.1 is available for download (Changelog).
  • +
  • June 2023. scikit-learn 1.3.0 is available for download (Changelog).
  • +
  • All releases: What's new (Changelog).
+

Community

- - Help us, donate! - Cite us! +

+ Help us, donate! + Cite us! +

+

Who uses scikit-learn?

-
-