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
1 change: 0 additions & 1 deletion docs/api/qiskit/1.4/qiskit.pulse.library.Constant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,3 @@ $$

<Attribute id="qiskit.pulse.library.Constant.alias" attributeValue="'Constant'" />
</Class>

2 changes: 1 addition & 1 deletion docs/guides/configure-error-mitigation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@
"\n",
"You can turn on and off individual error mitigation and suppression methods, including dynamical decoupling, gate and measurement twirling, measurement error mitigation, PEC, and ZNE. See [Error mitigation and suppression techniques](error-mitigation-and-suppression-techniques) for an explanation of each.\n",
"\n",
"<Admonition type = \"note\" title = \"Notes\">\n",
"<Admonition type=\"note\" title=\"Notes\">\n",
"- Not all options are available for both primitives. See the [available options table](runtime-options-overview#options-table) for the list of available options.\n",
"- Not all methods work together on all types of circuits. See the [feature compatibility table](runtime-options-overview#options-compatibility-table) for details.\n",
"</Admonition>\n",
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/configure-error-suppression.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"\n",
"In the primitives, you can explicitly enable and disable individual error mitigation and suppression methods, such as dynamical decoupling.\n",
"\n",
"<Admonition type = \"note\" title = \"Notes\">\n",
"<Admonition type=\"note\" title=\"Notes\">\n",
"- Not all options are available for both primitives. See the [available options](runtime-options-overview#options-table) table for the list of available options.\n",
"- Not all methods work together on all types of circuits. See the [feature compatibility](runtime-options-overview#options-compatibility-table) table for details.\n",
"</Admonition>"
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/install-qiskit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Whether you will work locally or in a cloud environment, the first step for all

It is recommended that you use [Python virtual environments](https://docs.python.org/3.10/tutorial/venv.html) to separate Qiskit from other applications.

<Admonition type = "note">
<Admonition type="note">
These instructions use the standard Python distribution from [pypi.org](https://pypi.org/). However, you can use other Python distributions, such as [Anaconda](https://docs.anaconda.com/anaconda/) or [miniconda](https://docs.anaconda.com/miniconda/), along with other dependency management workflows like [Poetry](https://python-poetry.org/docs/).
</Admonition>

Expand Down
4 changes: 2 additions & 2 deletions docs/guides/qiskit-addons-sqd-get-started.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"id": "db4db859-4190-42a5-b512-1128eeaf82db",
"metadata": {},
"source": [
"<Admonition type = \"note\">\n",
"<Admonition type=\"note\">\n",
"This example ingests pre-generated data in a file called `n2_fci.txt`, which contains one- and two-body electronic integrals. To run the code cells below on a local machine, copy and paste the data into a file with the same name. This example also requires the `pyscf` package to be installed.\n",
"</Admonition>\n",
"\n",
Expand Down Expand Up @@ -1768,7 +1768,7 @@
"\n",
"However, these choices are problem specific and out of scope for this guide. Instead, to demonstrate the SQD workflow, we will generate a random set of counts for the configuration recovery loop to post-process. This simulates the measurement data of a 32-qubit circuit sampled with 10,000 shots. After the count data has been generated, the `recover_configurations()` method requires that you convert the count data into a matrix of the bitstrings measured at each shot, as well as an array of probabilities for each state that was measured.\n",
"\n",
"<Admonition type = \"note\">\n",
"<Admonition type=\"note\">\n",
"The artificial generation of samples is only used as a means to demonstrate the tooling of `qiskit-addon-sqd`. The package is meant to be used as part of a larger workflow wherein an ansatz or other circuit is defined, optimized, and executed using the Sampler primitive. The code cell below contains commented-out code demonstrating what a typical workflow might look like given a circuit ansatz transpiled to an ISA circuit.\n",
"</Admonition>"
]
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/quick-start.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"\n",
"- To install Python, first check the \"Programming Language\" section on the [Qiskit PyPI project page](https://pypi.org/project/qiskit/) to determine which Python versions are supported by the most recent release. For download instructions, see the [Python Beginners Guide.](https://wiki.python.org/moin/BeginnersGuide/Download)\n",
"\n",
"<Admonition type = \"note\">\n",
"<Admonition type=\"note\">\n",
Copy link
Member Author

Choose a reason for hiding this comment

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

The only discrepancy I found between the JS and Rust MDX libraries is that the Rust library doesn't allow spaces here. This only occurs in a handful of places in our repo.

"These instructions use the standard Python distribution from [pypi.org](https://pypi.org/). However, you can use other Python distributions, such as [Anaconda](https://docs.anaconda.com/anaconda/) or [miniconda](https://docs.anaconda.com/miniconda/), along with other dependency management workflows like [Poetry](https://python-poetry.org/docs/).\n",
"</Admonition>\n",
"</details>\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
"\n",
"### Computational complexity\n",
"\n",
"In cryptography, the *computational complexity class* [**NP (non-deterministic polynomial time)**](https://en.wikipedia.org/w/index.php?title=NP_(complexity)&oldid=1158889203) plays an important role. This class consists of decision problems for which proposed solutions can be verified in polynomial time using a <DefinitionTooltip definition= \"Machine that operates on an infinite tape containing symbols which has a read/write head that can move left or right on the tape and change the symbols according to a set of predetermined rules. In a deterministic Turing machine, the transition from one state to another is uniquely determined by the current state and the symbol being read from the tape. This means that for any given configuration of the machine, there is only one possible next step.\">deterministic Turing machine</DefinitionTooltip> (DTM). The importance of NP stems from the fact that it is conjectured to consist of many computational problems that cannot be solved efficiently by both classical and quantum computers.\n",
"In cryptography, the *computational complexity class* [**NP (non-deterministic polynomial time)**](https://en.wikipedia.org/w/index.php?title=NP_(complexity)&oldid=1158889203) plays an important role. This class consists of decision problems for which proposed solutions can be verified in polynomial time using a <DefinitionTooltip definition=\"Machine that operates on an infinite tape containing symbols which has a read/write head that can move left or right on the tape and change the symbols according to a set of predetermined rules. In a deterministic Turing machine, the transition from one state to another is uniquely determined by the current state and the symbol being read from the tape. This means that for any given configuration of the machine, there is only one possible next step.\">deterministic Turing machine</DefinitionTooltip> (DTM). The importance of NP stems from the fact that it is conjectured to consist of many computational problems that cannot be solved efficiently by both classical and quantum computers.\n",
"\n",
"The first generation of successful asymmetric key cryptosystems developed in the 1970s based their security on mathematical problems such as prime factorization and discrete logarithms that are now conjectured to belong to the **NP-intermediate** subclass of NP. This subclass consists of problems that are believed not to have polynomial-time solutions on DTMs but at the same time are also not as hard as the hardest problems in NP.\n",
"\n",
Expand Down
81 changes: 80 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"save-internal-links": "tsx scripts/js/commands/saveInternalLinks.ts"
},
"dependencies": {
"@qiskit/mdx-link-extract": "^1.0.0",
"cheerio": "^1.0.0-rc.12",
"cspell": "^8.12.1",
"fast-levenshtein": "^3.0.0",
Expand Down
99 changes: 0 additions & 99 deletions scripts/js/lib/links/extractLinks.test.ts
Copy link
Member Author

Choose a reason for hiding this comment

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

This file was deleted.

90 changes: 13 additions & 77 deletions scripts/js/lib/links/extractLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,11 @@

import path from "node:path";

import { visit } from "unist-util-visit";
import { unified } from "unified";
import remarkStringify from "remark-stringify";
import remarkMdx, { Root } from "remark-mdx";
import remarkGfm from "remark-gfm";
import remarkParse from "remark-parse";
import frontmatter from "remark-frontmatter";
import remarkMath from "remark-math";
import { extractFromFile } from "@qiskit/mdx-link-extract";

import { ObjectsInv } from "../api/objectsInv.js";
import { readMarkdown } from "../markdownReader.js";
import { removePrefix, removeSuffix } from "../stringUtils.js";
import { partition } from "lodash-es";

export type ParsedFile = {
/** Anchors that the file defines. These can be linked to from other files. */
Expand All @@ -34,71 +27,6 @@ export type ParsedFile = {
externalLinks: Set<string>;
};

// Keep in sync with the function `getHeadingAnchorId` in closed source"
export function parseAnchors(markdown: string): Set<string> {
const lines = markdown.split("\n");
const anchors = new Set<string>();
for (const line of lines) {
const heading = line.match(/^\s*#{1,6}\s+(.+?)\s*$/);
if (heading) {
const normalized = heading[1]
.toLowerCase()
.trim()
.replaceAll(" ", "-")
.replaceAll(/[\.,;:!?`\\\(\)"']/g, "");
let deduplicated = normalized;
let i = 1;
while (anchors.has(`#${deduplicated}`)) {
deduplicated = `${normalized}-${i}`;
i += 1;
}
anchors.add(`#${deduplicated}`);
}
const id = line.match(/(?<=id=")(.+?)(?=")/);
if (id) anchors.add(`#${id[1]}`);
}
return anchors;
}

export async function parseLinks(
markdown: string,
): Promise<[Set<string>, Set<string>]> {
const internalLinks = new Set<string>();
const externalLinks = new Set<string>();

const addLink = (link: string): void => {
// We cannot check that email addresses are valid.
if (link.startsWith("mailto:")) return;

if (link.startsWith("http")) {
externalLinks.add(link);
} else {
internalLinks.add(link);
}
};

const tree = unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkMath)
.use(remarkMdx)
.use(frontmatter)
.parse(markdown);

visit(tree, (node: any) => {
if (node.type === "link" || node.type === "image") {
addLink(node.url);
} else if (node.type === "mdxJsxTextElement" && node.name === "a") {
const href = node.attributes.find((attr: any) => attr.name == "href");
if (href) {
addLink(href.value);
}
}
});

return [internalLinks, externalLinks];
}

async function parseObjectsInv(filePath: string): Promise<Set<string>> {
const objinv = await ObjectsInv.fromFile(
removeSuffix(filePath, "objects.inv"),
Expand Down Expand Up @@ -128,10 +56,18 @@ export async function parseFile(filePath: string): Promise<ParsedFile> {
externalLinks: new Set(),
};

const markdown = await readMarkdown(filePath);
try {
const [internalLinks, externalLinks] = await parseLinks(markdown);
return { anchors: parseAnchors(markdown), internalLinks, externalLinks };
const [links, anchors] = await extractFromFile(filePath);
const [externalLinks, internalLinks] = partition(
// We can't check emails are valid
links.filter((x) => !x.startsWith("mailto:")),
(link) => link.startsWith("http"),
);
return {
anchors: new Set(anchors),
internalLinks: new Set(internalLinks),
externalLinks: new Set(externalLinks),
};
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : `${err}`;
throw new Error(`Problem parsing '${filePath}':\n` + msg);
Expand Down