=== Jeet Anchor Checker ===
Contributors: jeetsanwal
Tags: anchor links, content audit, broken links, documentation
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Find section links missing from saved WordPress content, letter-case mismatches, and duplicate HTML anchors. Small batches, no crawling, no content edits.

== Description ==

Jeet Anchor Checker helps maintain tutorials, documentation, and growing content libraries. When a heading changes, a section link may no longer point where you expect.

Open Tools > Anchor Checker, choose your public content types, and start a scan. The checker reads published content in small batches and gives you a report with an edit-source link and a live-target link.

Features:

* Same-page and cross-page fragment links in stored content.
* Exact, case-sensitive HTML ID matching, including percent-encoded UTF-8 fragments.
* Letter-case suggestions and duplicate-ID findings.
* Legacy <a name="..."> anchors and saved Gutenberg HTML.
* Published posts, pages, and public custom post types.
* Start, pause, resume, progress, finding filters, and a paginated report.
* Administrator-only access; no frontend scripts or styles.
* No ads, Pro version, account, tracking, external services, or remote crawling.

= Accurate scope =

This plugin audits saved post_content, not the complete rendered website. It never executes shortcodes, dynamic blocks, content filters, or arbitrary rendering callbacks. A finding says "Not found in checked content" because a theme or JavaScript might supply an ID at runtime.

Targets with detected shortcodes, dynamic/third-party blocks, supported builder metadata, incomplete snapshots, or URLs outside the chosen content need a live-page check. Theme templates, menus, widgets, comments, archives, external websites, builder-only content, generated table-of-contents IDs, and JavaScript-generated links are outside this scan. Saved Gutenberg HTML with explicit anchors is included; dynamically generated block HTML is not rendered.

The checker does not fetch URLs, verify HTTP status, follow redirects, automatically repair links, or guarantee that a link is broken on the live page. Links with empty fragments, browser-top fragments, text-only fragment directives, non-HTTP schemes, and external hosts are skipped or treated as browser navigation where appropriate.

= Bounded work =

Each request reads at most 5 items or checks at most 50 distinct stored hrefs. A scan covers up to 2,000 items, 8 MB of snapshots, and 1,000 stored findings. Each content item is limited to 1 MB, 1,500 anchors, and 1,000 fragment hrefs. Visible notices explain limits; missing targets in incomplete content remain unverified. Narrow the selected content types for a large site.

Keep the tools tab open during a scan. Closing it stops further requests; returning lets you resume the saved scan. Results reflect the content captured when indexed; scan again after editing. Scans are isolated per administrator and per WordPress site.

== Installation ==

1. Upload the jeet-anchor-checker ZIP in Plugins > Add New > Upload Plugin.
2. Activate Jeet Anchor Checker.
3. Open Tools > Anchor Checker.
4. Select the content types and choose Start new scan.

== Frequently Asked Questions ==

= Does this change my links? =

No. It reports findings and opens the existing WordPress editor for you to review and fix content.

= Is a "Not found" finding definitely a broken live link? =

No. It means the target ID was absent from the checked content snapshot. Check the live target first: your theme, scripts, or another plugin may add it. Detected dynamic or incomplete content is marked for a live-page check instead.

= Does it include private or password-protected pages? =

No. Only published, publicly viewable, non-password-protected content in the selected public post types is included.

= Does it crawl external URLs? =

No. URL resolution uses the current site's known WordPress posts and permalinks without HTTP requests. External hosts, files, and non-post URLs are not crawled.

= Where is the report stored? =

Temporary WordPress transients store parsed IDs, links, post titles, URLs, and the report. They are private to each administrator and site. Reports expire after an hour of inactivity; individual snapshots expire one hour after they were read. An expired snapshot becomes unverified. Start a fresh scan if a long pause expires the data. Uninstall removes this plugin's temporary data on the current site. WordPress or your persistent object cache may keep expired keys until its normal expiry cleanup.

= Is anything sent to Jeet Sanwal or a third party? =

No. The plugin has no telemetry, advertising, account signup, remote API, or frontend credit link.

= Can a multisite network administrator use this? =

Yes, within each site's Tools screen when they have manage_options. Reports belong to the current site. There is no network-wide scanner.

== Changelog ==

= 1.0.0 =
* First release: bounded stored-content scans, case-aware anchor checks, duplicate IDs, dynamic-content coverage notes, pause/resume, and filtered reports.
