Metadata-Version: 2.4
Name: sphinx-hackerrank
Version: 2026.10.31
Summary: Build portable HackerRank Interviewer Guidelines from Sphinx documentation.
Author-email: Adam Dangoor <adamdangoor@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Rippling
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Issues, https://github.com/adamtheturtle/sphinx-hackerrank/issues
Project-URL: Source, https://github.com/adamtheturtle/sphinx-hackerrank
Keywords: documentation,rst,sphinx
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Web Environment
Classifier: Framework :: Sphinx :: Extension
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Requires-Python: >=3.12
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: beautifulsoup4>=4.15.0
Requires-Dist: docutils>=0.21.2
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: sphinx<10,>=9.1.1
Requires-Dist: sphinx-jinja2>=0.0.1
Requires-Dist: sphinx-toolbox<5,>=4.3.1
Dynamic: license-file

|Build Status| |PyPI|

sphinx-hackerrank
=================

Build portable Interviewer Guidelines from maintained Sphinx guides.

* Reuse Sphinx's HTML renderer.
* Export one standalone HTML fragment per question and language, plus a local preview index.
* Build and preview without a HackerRank login or API token.

.. contents::

Installation
------------

* Requires Python 3.12+ and Sphinx 9.1.1+.
* Installed packages need no ``sys.path`` changes.

Install from PyPI:

.. code-block:: console

   pip install sphinx-hackerrank

Or install a wheel from the GitHub release assets:

.. code-block:: console

   pip install https://github.com/adamtheturtle/sphinx-hackerrank/releases/download/2026.10.30.2/sphinx_hackerrank-2026.10.30.2-py3-none-any.whl

Enable the extension in ``conf.py``:

.. code-block:: python

   """Sphinx configuration."""

   extensions = ["sphinx_hackerrank"]

Authoring
---------

Keep the full guide and its Interviewer Guideline RST beside each other.
Define the layout in the consuming project's ``conf.py``:

.. code-block:: python

   """Sphinx configuration."""

   from sphinx_hackerrank.layout import GuidelineLayout, SectionGroup

   hackerrank_guideline_layout = GuidelineLayout(
       part_marker="Brief",
       groups=(
           SectionGroup(title="Work", sections=("Brief",)),
           SectionGroup(
               title="Examples",
               sections=("Cases",),
               include_headings=("Cases",),
           ),
       ),
       trailing_sections=("Review",),
       introduction="See the `source guide <{source_url}>`_.",
   )

The Interviewer Guideline RST then needs one directive:

.. code-block:: rst

   .. interviewer-guideline:: guide.rst

The package has no built-in section names, grouping rules, or introductory wording.
The configured marker identifies parts by a direct subsection with that heading.
Groups select source headings and combine their content under the supplied display title.
``include_headings`` retains the listed source headings inside a group.
``trailing_sections`` selects optional sections to show after the parts.
``introduction`` is RST supplied by the consumer, with ``{source_url}`` replaced by the configured guide URL.
Its default is empty.

The directive derives its page title from the guide and its languages from the adjacent question mapping.
Selected sections can be nested beneath other selections without requiring parent paths in the layout.
They appear once in their own group.
Empty groups are omitted after admonitions are removed.
A missing layout, missing mappings, missing parts, or ambiguous selected headings fail the build.
Changing the guide, mapping, or configured layout refreshes the view.

For other layouts, include native sections by exact heading path or an existing RST section label:

.. code-block:: rst

   .. container:: hr-interviewer-guideline interviewer-guideline-python

      .. collapse:: Prompt

         .. interviewer-guideline-section:: widgets.rst
            :section: Part 1 / Prompt
            :language: python

* Use ``:section: #widget-prompt`` to select a labelled section.
* Add ``:include-heading:`` to retain the selected section's heading.
* Nested headings become rubrics inside disclosures.
* Build with ``-W`` to reject missing or ambiguous selections as directive errors.
* Sections come from the full guide without extraction markers or duplicated content.
* Native includes, substitutions, and the guide's existing Jinja templates are supported.
* Variants are cached within each Interviewer Guideline read and discarded before Sphinx persists the document tree.
* Guide and included-file dependencies are tracked for incremental builds.

Subsection exclusions
---------------------

Keep the guide's existing heading hierarchy when composing separate disclosures.
Use ``:exclude-sections:`` to omit subsections from a parent selection:

.. code-block:: rst

   .. interviewer-guideline-section:: widgets.rst
      :section: Part 1 / Prompt
      :language: python
      :exclude-sections: Follow up questions

   .. interviewer-guideline-section:: widgets.rst
      :section: Part 1 / Prompt / Follow up questions
      :language: python

* Exclusions are heading paths relative to the selected section, or section labels within it.
* List multiple exclusions on separate indented lines.
* Missing or ambiguous exclusions fail the build, as does excluding the selected section itself.
* Exclusions affect only the copied view.
  The source guide and other selections retain their content.

Language contexts
-----------------

Configure how each language renders the guide's Jinja context:

.. code-block:: python

   """Sphinx configuration."""

   hackerrank_jinja_context = "snippets"
   hackerrank_languages = {
       "python": {
           "name": "Python",
           "context": {"variants": [{"name": "Python", "lexer": "python"}]},
       },
   }

* ``context`` overrides values in the configured Jinja context while that variant is parsed.
  The original configuration is restored afterwards.
* ``name`` identifies redundant language disclosures to flatten in copied content.
* Other part, category, and test-alternative disclosures remain intact.
* Admonitions are omitted within ``hr-interviewer-guideline`` containers by default.
  Set ``hackerrank_exclude_admonitions = False`` to retain them.
  The full guide's admonitions are unaffected.

Question mappings
-----------------

Create a mapping beside each Interviewer Guideline, such as ``widgets-interviewer-guideline.yml`` beside ``widgets-interviewer-guideline.rst``:

.. code-block:: yaml

   version: 1
   questions:
     - language: python
       name: Widgets - Python

* ``hackerrank_manifest_pattern`` defaults to ``**/*-interviewer-guideline.yml``, relative to Sphinx's source directory.
* Nested directories and custom source layouts are supported.
* The builder reads the language and name.
  Your publishing tool can manage extra fields such as question IDs.

Build and preview
-----------------

.. code-block:: console

   sphinx-build -W -b hackerrank docs build/hackerrank

* Open ``build/hackerrank/interviewer-guidelines/index.html`` to select a question and language.
* Each preview uses the same self-contained HTML that can be saved as HackerRank Interviewer Guidelines.
* Each code block has a keyboard-accessible **Copy code** button that preserves whitespace.
* Copy buttons use JavaScript bundled with the output.
  Hosts must allow that script to run for the buttons to appear.
* Native disclosure elements and code remain usable without JavaScript.
* The builder also produces ordinary themed HTML pages.
  The extension's directives work in the standard ``html`` builder too.
* Sphinx's native ``only`` directive can select ``builder_hackerrank``, ``builder_html``, or the shared ``html`` format tag.

Source links
------------

By default, links to full guide pages point back into the local HTML build.
To target a hosted documentation or source site, configure:

.. code-block:: python

   """Sphinx configuration."""

   hackerrank_source_url = "https://example.org/guides/"
   hackerrank_source_suffix = ".html"
   hackerrank_source_anchors = True

* Set ``hackerrank_source_suffix`` to ``.rst`` when linking to source files.
* Set ``hackerrank_source_anchors = False`` when the destination does not support anchors.
* External URLs and links within a fragment are retained.

Publishing
----------

* Use a separate publishing tool to call the HackerRank API and manage credentials, question identities, candidate prompts, or projects.
* Your publishing tool can read the generated fragments and verify saved Interviewer Guidelines.

Use ``sphinx_hackerrank.html.html_equivalent`` to compare generated and saved HTML.
It tolerates entity encoding, block indentation, and HackerRank's column-width formatting.
Literal whitespace in code, scripts, styles, and text areas is preserved, as are spaces separating inline elements and disclosure attributes.
``normalize_html(html=...)`` exposes the normalized representation when needed.
The comparison can be passed as the ``notes_equal`` callback to the HackerRank SDK's ``questions.update_internal_notes()`` method.

Contributing
------------

See `CONTRIBUTING.rst <./CONTRIBUTING.rst>`_ for setup, linting, tests, and releases.

* The sample under ``sample/source`` uses a custom Jinja context and nested guide files.
* The wheel smoke test installs the built wheel into a fresh environment and builds that sample outside the checkout.

License
-------

MIT.
See ``LICENSE``.

.. |Build Status| image:: https://github.com/adamtheturtle/sphinx-hackerrank/actions/workflows/ci.yml/badge.svg?branch=main
   :target: https://github.com/adamtheturtle/sphinx-hackerrank/actions
.. |PyPI| image:: https://badge.fury.io/py/sphinx-hackerrank.svg
   :target: https://badge.fury.io/py/sphinx-hackerrank
