Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions docs/manifest/writing/assertions-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,11 +280,6 @@ The [C2PA Technical Specification](https://c2pa.org/specifications/specification

V1 actions are fully specified in the `actions` array. However, a v2 action may either be fully specified in an element of the `actions` array or it may be derived from an element in the `templates` array with the same action name.

<div style={{display: 'none'}}>
The CAI APIs can read all v2 actions and write **most** v2 actions.
We should document v2 actions that can it NOT write.
</div>

### Action names

The value of the `action` property must be either one of the pre-defined [standard C2PA action strings](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_actions) of the form `c2pa.*` or a custom action name. The set of standard C2PA actions includes fundamental ones as `c2pa.created` for when an asset is first created, and others (`c2pa.cropped`, `c2pa.resized`, and so on) for when an asset's content is modified in some way.
Expand Down
6 changes: 5 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const darkCodeTheme = require('prism-react-renderer').themes.dracula;
const remoteDocs = require('./remote-docs.json');
const { readFileSync } = require('fs');
const { resolve } = require('path');
const remarkStripHiddenLinks = require('./src/remark/remark-strip-hidden-links');

const copyright = `
<div style="font-size: 0.75rem;">
Expand Down Expand Up @@ -164,7 +165,10 @@ async function createConfig() {
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
beforeDefaultRemarkPlugins: [remarkGithubAdmonitionsToDirectives],
beforeDefaultRemarkPlugins: [
remarkGithubAdmonitionsToDirectives,
remarkStripHiddenLinks,
],
sidebarPath: require.resolve('./sidebars.js'),
editUrl: ({ docPath, versionDocsDirPath }) => {
const normalizedDocPath = docPath.toLowerCase();
Expand Down
19 changes: 14 additions & 5 deletions remote-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,20 @@
"dest": "docs/rust-sdk/docs/release-notes.md",
"sidebar": {
"category": "rust-sdk",
"label": "Release notes",
"label": "Release notes (Rust)",
"order": 10
}
},

{
"repo": "contentauth/c2pa-rs",
"path": "docs/instanceid_behavior.md",
"dest": "docs/rust-sdk/docs/instanceid-behavior.md",
"sidebar": {
"category": "rust-sdk",
"label": "InstanceID behavior",
"order": 11
}
},
{ "_comment": "Working with the SDK" },
{
"repo": "contentauth/c2pa-rs",
Expand Down Expand Up @@ -278,7 +287,7 @@
"dest": "docs/c2pa-python/docs/release-notes.md",
"sidebar": {
"category": "c2pa-python",
"label": "Release notes",
"label": "Release notes (Python)",
"order": 9
}
},
Expand Down Expand Up @@ -326,7 +335,7 @@
"dest": "docs/c2pa-cpp/docs/context-settings.md",
"sidebar": {
"category": "c2pa-cpp",
"label": "Configuring the SDK",
"label": "Configuring SDK settings",
"order": 3
}
},
Expand Down Expand Up @@ -376,7 +385,7 @@
"dest": "docs/c2pa-cpp/docs/release-notes.md",
"sidebar": {
"category": "c2pa-cpp",
"label": "Release notes",
"label": "Release notes (C++",
"order": 8
}
},
Expand Down
72 changes: 72 additions & 0 deletions src/remark/remark-strip-hidden-links.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Docusaurus's broken-link checker collects links from rendered <a> elements
* regardless of CSS visibility, so links inside GitHub-only content (hidden on
* this site via the "github-only" class or a display:none style, but meant to
* work when the source markdown is viewed on GitHub) get flagged as broken.
*
* This plugin unwraps markdown links found inside such hidden containers,
* before they become <a> elements, so they're never collected.
*/

const CLASS_RE = /(^|\s)github-only(\s|$)/;
const DISPLAY_NONE_RE = /display\s*:\s*['"]none['"]/;

function isHiddenDiv(node) {
if (
!node ||
(node.type !== 'mdxJsxFlowElement' && node.type !== 'mdxJsxTextElement') ||
node.name !== 'div'
) {
return false;
}
const attributes = node.attributes || [];
return attributes.some((attr) => {
if (attr.type !== 'mdxJsxAttribute') return false;
if (
(attr.name === 'class' || attr.name === 'className') &&
typeof attr.value === 'string'
) {
return CLASS_RE.test(attr.value);
}
if (attr.name === 'style') {
const raw =
attr.value && typeof attr.value === 'object'
? attr.value.value
: attr.value;
return typeof raw === 'string' && DISPLAY_NONE_RE.test(raw);
}
return false;
});
}

// Replace link/linkReference nodes with their child content, in place.
function stripLinks(node) {
if (!node || !Array.isArray(node.children)) return;
node.children = node.children.flatMap((child) => {
stripLinks(child);
if (child.type === 'link' || child.type === 'linkReference') {
return child.children || [];
}
return [child];
});
}

function visit(node) {
if (!node) return;
if (isHiddenDiv(node)) {
// stripLinks recurses through the whole hidden subtree itself.
stripLinks(node);
return;
}
if (Array.isArray(node.children)) {
node.children.forEach((child) => visit(child));
}
}

function remarkStripHiddenLinks() {
return (tree) => {
visit(tree);
};
}

module.exports = remarkStripHiddenLinks;
Loading