From f53bd529833f018d14d44cff208eb88d43034875 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Thu, 25 Apr 2024 20:27:23 -0700 Subject: [PATCH] Remove trailing empty Text() objects that get displayed as newlines. --- rich_rst/__init__.py | 23 +- tests/test_vectors/bullet_list.rst | 2 + tests/test_vectors/bullet_list_expected.html | 18 ++ tests/test_vectors/directives_expected.html | 14 +- tests/test_vectors/introduction_expected.html | 57 +++-- .../test_vectors/specification_expected.html | 228 +++++++++++------- 6 files changed, 230 insertions(+), 112 deletions(-) create mode 100644 tests/test_vectors/bullet_list.rst create mode 100644 tests/test_vectors/bullet_list_expected.html diff --git a/rich_rst/__init__.py b/rich_rst/__init__.py index 7d6c897..647e1fa 100644 --- a/rich_rst/__init__.py +++ b/rich_rst/__init__.py @@ -20,7 +20,7 @@ import rich from rich import box from rich.align import Align -from rich.console import Console, ConsoleOptions, RenderResult +from rich.console import Console, ConsoleOptions, RenderResult, NewLine from rich.jupyter import JupyterMixin from rich.panel import Panel from rich.style import Style @@ -286,7 +286,7 @@ def visit_bullet_list(self, node): self.renderables.append(Text(list_item.astext().replace("\n", " "), style=text_style)) self.renderables.append(Text(" • ", end="", style=marker_style)) self.renderables.append(Text(list_item.astext().replace("\n", " "), style=text_style)) - self.renderables.append(Text()) + self.renderables.append(NewLine()) raise docutils.nodes.SkipChildren() def visit_enumerated_list(self, node): @@ -296,7 +296,7 @@ def visit_enumerated_list(self, node): self.renderables.append(Text(f" {i}", end=" ", style=marker_style)) self.renderables.append(Text(list_item.astext().replace("\n", " "), style=text_style)) - self.renderables.append(Text()) + self.renderables.append(NewLine()) raise docutils.nodes.SkipChildren() def visit_literal(self, node): @@ -607,9 +607,20 @@ def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderR ) document.walkabout(visitor) - if visitor.renderables and isinstance(visitor.renderables[-1], Text): - visitor.renderables[-1].rstrip() - visitor.renderables[-1].end = "\n" + # Strip all trailing newlines and newline-like rich objects + while visitor.renderables: + if isinstance(visitor.renderables[-1], Text): + visitor.renderables[-1].rstrip() + visitor.renderables[-1].end = "\n" + if visitor.renderables[-1]: # The Text object still contains data. + break + else: + visitor.renderables.pop() + elif isinstance(visitor.renderables[-1], NewLine): + visitor.renderables.pop() + else: + break + for renderable in visitor.renderables: yield from console.render(renderable, options) if self.log_errors and visitor.errors: diff --git a/tests/test_vectors/bullet_list.rst b/tests/test_vectors/bullet_list.rst new file mode 100644 index 0000000..0beb3ff --- /dev/null +++ b/tests/test_vectors/bullet_list.rst @@ -0,0 +1,2 @@ +* foo +* bar diff --git a/tests/test_vectors/bullet_list_expected.html b/tests/test_vectors/bullet_list_expected.html new file mode 100644 index 0000000..77e3f8b --- /dev/null +++ b/tests/test_vectors/bullet_list_expected.html @@ -0,0 +1,18 @@ + + + + + + + +
foo
+bar
+
+ + diff --git a/tests/test_vectors/directives_expected.html b/tests/test_vectors/directives_expected.html index 2b9c51e..416e5e1 100644 --- a/tests/test_vectors/directives_expected.html +++ b/tests/test_vectors/directives_expected.html @@ -123,10 +123,10 @@ note tip warning + Any text immediately following the directive indicator (on the same line and/or indented on following lines) is interpreted as a directive block and is parsed for normal body elements. For example, the following "note" admonition directive contains one paragraph and a bullet list consisting of two list items: - ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ .. note:: This is a note admonition. This is the second line of the first paragraph. @@ -767,8 +767,8 @@ Block markup and inline markup within cells is supported. Line ends are recognized within cells. There is no support for checking that the number of columns in each row is the same. The directive automatically adds empty entries at the end of short rows. Add "strict" option to verify input? -Example: +Example: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ .. csv-table:: Frozen Delights! :header: "Treat", "Quantity", "Description" @@ -1175,9 +1175,11 @@ hexadecimal numbers, prefixed by 0x, x, \x, U+, u, or \u or as XML-style hexadecimal character entities, e.g. &#x hexadecimal numbers, prefixed by 0x, x, \x, U+, u, or \u or as XML-style hexadecimal character entities, e.g. &#x1a2b text, which is used as-is. + Text following " .. " is a comment and is ignored. The spaces between the arguments are ignored and thus do not appear -in the output. Hexadecimal codes are case-insensitive.For example, the following text: +in the output. Hexadecimal codes are case-insensitive. +For example, the following text: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ Copyright |copy| 2003, |BogusMegaCorp (TM)| |---| all rights reserved. @@ -1449,10 +1451,14 @@ accented characters to the base character, non-alphanumeric characters to hyphens, consecutive hyphens into one hyphen + and stripping + leading hyphens and number characters, and trailing hyphens. + For example "Rot.Gelb&Grün:+2008" becomes "rot-gelb-grun-2008" and "1000_Steps!" becomes "steps". + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Rationale: ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -1466,10 +1472,12 @@ The CSS1 spec defines identifiers based on the "name" token ("flex" tokenizer notation below; "latin1" and "escape" 8-bit characters have been replaced with XML entities): unicode \\[0-9a-f]{1,4} latin1 [&iexcl;-&yuml;] escape {unicode}|\\[ -~&iexcl;-&yuml;] nmchar [-A-Za-z0-9]|{latin1}|{escape} name {nmchar}+ + The CSS1 rule requires underscores ("_"), colons (":"), and periods (".") to be escaped , therefore "classes" and "ids" attributes should not contain these characters. Combined with HTML4.1 requirements (the first character must be a letter; no "unicode", "latin1", or "escape" characters), this results in the regular expression [A-Za-z][-A-Za-z0-9]*. Docutils adds a normalization by downcasing and merge of consecutive hyphens. + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Custom Interpreted Text Roles ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ diff --git a/tests/test_vectors/introduction_expected.html b/tests/test_vectors/introduction_expected.html index 5166481..754a8ff 100644 --- a/tests/test_vectors/introduction_expected.html +++ b/tests/test_vectors/introduction_expected.html @@ -7,7 +7,7 @@ .r2 {color: #bd93f9; text-decoration-color: #bd93f9; background-color: #282a36; text-decoration: underline} .r3 {color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #282a36} .r4 {color: #f1fa8c; text-decoration-color: #f1fa8c; font-weight: bold} -.r5 {font-style: italic} +.r5 {color: #f8f8f2; text-decoration-color: #f8f8f2; background-color: #282a36; font-style: italic} .r6 {color: #ffffff; text-decoration-color: #ffffff} .r7 {color: #bcbcbc; text-decoration-color: #bcbcbc} body { @@ -57,9 +57,12 @@ the establishment of a set of standard conventions allowing the expression of structure within plaintext, and the conversion of such documents into useful structured data formats. + The secondary goal of reStructuredText is to be accepted by the Python community (by way of being blessed by PythonLabs -and the BDFL ) as a standard for Python inline documentation (possibly one of several standards, to account for -taste).To clarify the primary goal, here are specific design goals, in order, beginning with the most important: +and the BDFL ) as a standard for Python inline documentation (possibly one of several standards, to account for taste). + +To clarify the primary goal, here are specific design goals, in order, beginning with the most important: + 1 Readable. The marked-up text must be easy to read without any prior knowledge of the markup language. It should be easily read in raw form as in processed form. 2 Unobtrusive. The markup that is used should be as simple and unobtrusive as possible. The simplicity of markup @@ -82,11 +85,17 @@ markup. 11 Output-format-neutral. The markup will be appropriate for processing to multiple output formats, and will not be bi toward any particular format. -The design goals above were used as criteria for accepting or rejecting syntax, or selecting between alternatives.It is -emphatically not the goal of reStructuredText to define docstring semantics, such as docstring contents or docstring -length. These issues are orthogonal to the markup syntax and beyond the scope of this specification.Also, it is not the -goal of reStructuredText to maintain compatibility with StructuredText or Setext. reStructuredText shamelessly steals -their great ideas and ignores the not-so-great.Author's note: + +The design goals above were used as criteria for accepting or rejecting syntax, or selecting between alternatives. + +It is emphatically not the goal of reStructuredText to define docstring semantics, such as docstring contents or +docstring length. These issues are orthogonal to the markup syntax and beyond the scope of this specification. + +Also, it is not the goal of reStructuredText to maintain compatibility with StructuredText or Setext. reStructuredText +shamelessly steals their great ideas and ignores the not-so-great. + +Author's note: + Due to the nature of the problem we're trying to solve (or, perhaps, due to the nature of the proposed solution), the above goals unavoidably conflict. I have tried to extract and distill the wisdom accumulated over the years in the Python Doc-SIG mailing list and elsewhere, to come up with a coherent and consistent set of syntax rules, and the above @@ -129,29 +138,37 @@ reference parser implementation, but it does not aspire to be the entire system. I don't want reStructuredText or a hypothetical Python documentation processor to die stillborn because of over-ambition. Most of all, I want to help ease the documentation chore, the bane of many a programmer. + Unfortunately I was sidetracked and stopped working on this project. In November 2000 I made the time to enumerate the problems of StructuredText and possible solutions, and complete the first draft of a specification. This first draft was posted to the Doc-SIG in three parts: + A Plan for Structured Text Problems With StructuredText reStructuredText: Revised Structured Text Specification + In March 2001 a flurry of activity on the Doc-SIG spurred me to further revise and refine my specification, the result of which you are now reading. An offshoot of the reStructuredText project has been the realization that a single markup scheme, no matter how well thought out, may not be enough. In order to tame the endless debates on Doc-SIG, a flexible Docstring Processing System framework needed to be constructed. This framework has become the more important of the two -projects; reStructuredText has found its place as one possible choice for a single component of the larger framework.The -project web site and the first project release were rolled out in June 2001, including posting the second draft of the -spec and the first draft of PEPs 256, 257, and 258 to the Doc-SIG. These documents and the project implementation -proceeded to evolve at a rapid pace. Implementation history details can be found in the project history file.In -November 2001, the reStructuredText parser was nearing completion. Development of the parser continued with the addition -of small convenience features, improvements to the syntax, the filling in of gaps, and bug fixes. After a long holiday -break, in early 2002 most development moved over to the other Docutils components, the "Readers", "Writers", and +projects; reStructuredText has found its place as one possible choice for a single component of the larger framework. + +The project web site and the first project release were rolled out in June 2001, including posting the second draft of +the spec and the first draft of PEPs 256, 257, and 258 to the Doc-SIG. These documents and the project implementation +proceeded to evolve at a rapid pace. Implementation history details can be found in the project history file. + +In November 2001, the reStructuredText parser was nearing completion. Development of the parser continued with the +addition of small convenience features, improvements to the syntax, the filling in of gaps, and bug fixes. After a long +holiday break, in early 2002 most development moved over to the other Docutils components, the "Readers", "Writers", and "Transforms". A "standalone" reader (processes standalone text file documents) was completed in February, and a basic -HTML writer (producing HTML 4.01, using CSS-1) was completed in early March.PEP 287, "reStructuredText Standard -Docstring Format", was created to formally propose reStructuredText as a standard format for Python docstrings, PEPs, -and other files. It was first posted to comp.lang.python and the Python-dev mailing list on 2002-04-02.Version 0.4 of -the reStructuredText and Docstring Processing System projects were released in April 2002. The two projects were -immediately merged, renamed to "Docutils", and a 0.1 release soon followed. +HTML writer (producing HTML 4.01, using CSS-1) was completed in early March. + +PEP 287, "reStructuredText Standard Docstring Format", was created to formally propose reStructuredText as a standard +format for Python docstrings, PEPs, and other files. It was first posted to comp.lang.python and the Python-dev mailing +list on 2002-04-02. + +Version 0.4 of the reStructuredText and Docstring Processing System projects were released in April 2002. The two +projects were immediately merged, renamed to "Docutils", and a 0.1 release soon followed. ┌─────────────────────────────────────────────────────── Footer ───────────────────────────────────────────────────────┐ First drafts of the PEPs: diff --git a/tests/test_vectors/specification_expected.html b/tests/test_vectors/specification_expected.html index 1c48a0f..11fe696 100644 --- a/tests/test_vectors/specification_expected.html +++ b/tests/test_vectors/specification_expected.html @@ -27,12 +27,11 @@ .r22 {color: #959077; text-decoration-color: #959077; background-color: #272822} .r23 {color: #50fa7b; text-decoration-color: #50fa7b; font-weight: bold} .r24 {color: #8be9fd; text-decoration-color: #8be9fd} -.r25 {font-style: italic} -.r26 {color: #ff5555; text-decoration-color: #ff5555} -.r27 {color: #8be9fd; text-decoration-color: #8be9fd; font-weight: bold} -.r28 {color: #ff79c6; text-decoration-color: #ff79c6; font-weight: bold} -.r29 {color: #50fa7b; text-decoration-color: #50fa7b} -.r30 {color: #bcbcbc; text-decoration-color: #bcbcbc} +.r25 {color: #ff5555; text-decoration-color: #ff5555} +.r26 {color: #8be9fd; text-decoration-color: #8be9fd; font-weight: bold} +.r27 {color: #ff79c6; text-decoration-color: #ff79c6; font-weight: bold} +.r28 {color: #50fa7b; text-decoration-color: #50fa7b} +.r29 {color: #bcbcbc; text-decoration-color: #bcbcbc} body { color: #f8f8f2; background-color: #282a36; @@ -172,10 +171,12 @@ lists), the content of literal blocks, and the content of explicit markup blocks (directives, footnotes, ...). + Any text whose indentation is less than that of the current level (i.e., unindented text or "dedents") ends the current -level of indentation.Since all indentation is significant, the level of indentation must be consistent. For example, -indentation is the sole markup indicator for block quotes: +level of indentation. +Since all indentation is significant, the level of indentation must be consistent. For example, indentation is the sole +markup indicator for block quotes: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ This is a top-level paragraph. @@ -256,8 +257,10 @@ backslash escapes the second. ) Escaped whitespace characters are removed from the output document together with the escaping backslash. This allows character-level inline markup. In URI context , backslash-escaped whitespace represents a single space. + Backslashes have no special meaning in literal context . Here, a single backslash represents a literal backslash, without having to double up. + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Reference Names ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -287,8 +290,8 @@ whitespace is normalized (one or more spaces, horizontal or vertical tabs, newlines, carriage returns, or form feeds, are interpreted as a single space), and case is normalized (all alphabetic characters are converted to lowercase). -For example, the following hyperlink references are equivalent: +For example, the following hyperlink references are equivalent: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ - `A HYPERLINK`_ - `a hyperlink`_ @@ -501,26 +504,35 @@ lower-case alphabet characters: a, b, c, ..., z. uppercase Roman numerals: I, II, III, IV, ..., MMMMCMXCIX (4999). lowercase Roman numerals: i, ii, iii, iv, ..., mmmmcmxcix (4999). + In addition, the auto-enumerator, "#", may be used to automatically enumerate a list. Auto-enumerated lists may begin with explicit enumeration, which sets the sequence. Fully auto-enumerated lists use arabic numerals and begin with 1. -(Auto-enumerated lists are new in Docutils 0.3.8.)The following formatting types are recognized: +(Auto-enumerated lists are new in Docutils 0.3.8.) + +The following formatting types are recognized: + suffixed with a period: "1.", "A.", "a.", "I.", "i.". surrounded by parentheses: "(1)", "(A)", "(a)", "(I)", "(i)". suffixed with a right-parenthesis: "1)", "A)", "a)", "I)", "i)". + While parsing an enumerated list, a new list will be started whenever: + An enumerator is encountered which does not have the same format and sequence type as the current list (e.g. "1.", "( produces two separate lists). The enumerators are not in sequence (e.g., "1.", "3." produces two separate lists). + It is recommended that the enumerator of the first list item be ordinal-1 ("1", "A", "a", "I", or "i"). Although other start-values will be recognized, they may not be supported by the output format. A level-1 [info] system message will -be generated for any list beginning with a non-ordinal-1 enumerator.Lists using Roman numerals must begin with "I"/"i" -or a multi-character value, such as "II" or "XV". Any other single-character Roman numeral ("V", "X", "L", "C", "D", -"M") will be interpreted as a letter of the alphabet, not as a Roman numeral. Likewise, lists using letters of the -alphabet may not begin with "I"/"i", since these are recognized as Roman numeral 1.The second line of each enumerated -list item is checked for validity. This is to prevent ordinary paragraphs from being mistakenly interpreted as list -items, when they happen to begin with text identical to enumerators. For example, this text is parsed as an ordinary -paragraph: +be generated for any list beginning with a non-ordinal-1 enumerator. + +Lists using Roman numerals must begin with "I"/"i" or a multi-character value, such as "II" or "XV". Any other +single-character Roman numeral ("V", "X", "L", "C", "D", "M") will be interpreted as a letter of the alphabet, not as a +Roman numeral. Likewise, lists using letters of the alphabet may not begin with "I"/"i", since these are recognized as +Roman numeral 1. +The second line of each enumerated list item is checked for validity. This is to prevent ordinary paragraphs from being +mistakenly interpreted as list items, when they happen to begin with text identical to enumerators. For example, this +text is parsed as an ordinary paragraph: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ A. Einstein was a really smart dude. @@ -566,8 +578,8 @@ A definition is a block indented relative to the term, and may contain multiple paragraphs and other body elements. There may be no blank line between a term line and a definition block (this distinguishes definition lists from block quotes). Blank lines are required before the first and after the last definition list item, but are optional in-between. -Example: +Example: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ term 1 Definition 1. @@ -593,8 +605,8 @@ To describe program variables. The term is the variable name, a classifier may be used to indicate the type of the variable (string, integer, etc.), and the definition describes the variable's use in the program. This usage of definition lists supports the classifier syntax of Grouch, a system for describing and enforcing a Python object schema. -Syntax diagram: +Syntax diagram: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ +----------------------------+ | term [ " : " classifier ]* | @@ -736,26 +748,34 @@ Old GNU-style "plus" options consist of one plus and an option letter ("plus" options are deprecated now, their use discouraged). DOS/VMS options consist of a slash and an option letter or word. + Please note that both POSIX-style and DOS/VMS-style options may be used by DOS or Windows software. These and other -variations are sometimes used mixed together. The names above have been chosen for convenience only.The syntax for -short and long POSIX options is based on the syntax supported by Python's getopt.py module, which implements an option -parser similar to the GNU libc getopt_long() function but with some restrictions. There are many variant option -systems, and reStructuredText option lists do not support all of them.Although long POSIX and DOS/VMS option words may -be allowed to be truncated by the operating system or the application when used on the command line, reStructuredText -option lists do not show or support this with any special syntax. The complete option word should be given, supported -by notes about truncation if and when applicable.Options may be followed by an argument placeholder, whose role and -syntax should be explained in the description text. Either a space or an equals sign may be used as a delimiter between -long options and option argument placeholders; short options ("-" or "+" prefix only) use a space or omit the delimiter. -Option arguments may take one of two forms: +variations are sometimes used mixed together. The names above have been chosen for convenience only. + +The syntax for short and long POSIX options is based on the syntax supported by Python's getopt.py module, which +implements an option parser similar to the GNU libc getopt_long() function but with some restrictions. There are many +variant option systems, and reStructuredText option lists do not support all of them. + +Although long POSIX and DOS/VMS option words may be allowed to be truncated by the operating system or the application +when used on the command line, reStructuredText option lists do not show or support this with any special syntax. The +complete option word should be given, supported by notes about truncation if and when applicable. + +Options may be followed by an argument placeholder, whose role and syntax should be explained in the description text. +Either a space or an equals sign may be used as a delimiter between long options and option argument placeholders; short +options ("-" or "+" prefix only) use a space or omit the delimiter. Option arguments may take one of two forms: + Begins with a letter ([a-zA-Z]) and subsequently consists of letters, numbers, underscores and hyphens ([a-zA-Z0-9_-] Begins with an open-angle-bracket (<) and ends with a close-angle-bracket (>); any characters except angle brackets a allowed internally. -Multiple option "synonyms" may be listed, sharing a single description. They must be separated by comma-space.There -must be at least two spaces between the option(s) and the description (which can also start on the next line). The -description may contain multiple body elements. The first line after the option marker determines the indentation of the -description. As with other types of lists, blank lines are required before the first option list item and after the -last, but are optional between option entries.Syntax diagram (simplified): +Multiple option "synonyms" may be listed, sharing a single description. They must be separated by comma-space. + +There must be at least two spaces between the option(s) and the description (which can also start on the next line). +The description may contain multiple body elements. The first line after the option marker determines the indentation of +the description. As with other types of lists, blank lines are required before the first option list item and after the +last, but are optional between option entries. + +Syntax diagram (simplified): ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ +----------------------------+-------------+ | option [" " argument] " " | description | @@ -797,9 +817,11 @@ 1 Expanded form: Paragraph: :: Literal block 2 Partially minimized form: Paragraph: :: Literal block 3 Fully minimized form: Paragraph:: Literal block + All whitespace (including line breaks, but excluding minimum indentation for indented literal blocks) is preserved. Blank lines are required before and after a literal block, but these blank lines are not included as part of the literal block. + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Indented Literal Blocks ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -1153,11 +1175,15 @@ whose first line begins with ".." followed by whitespace (the "explicit markup start"), whose second and subsequent lines (if any) are indented relative to the first, and which ends before an unindented line. + Explicit markup blocks are analogous to field list items. The maximum common indentation is always removed from the second and subsequent lines of the block body. Therefore, if the first construct fits in one line and the indentation of the first and second constructs should differ, the first construct should not begin on the same line as the explicit -markup start.Blank lines are required between explicit markup blocks and other elements, but are optional between -explicit markup blocks where unambiguous. +markup start. + +Blank lines are required between explicit markup blocks and other elements, but are optional between explicit markup +blocks where unambiguous. + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Footnotes ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -1174,13 +1200,16 @@ a single "#" (denoting auto-numbered footnotes), a "#" followed by a simple reference name (an autonumber label), or a single "*" (denoting auto-symbol footnotes). + The footnote content (body elements) must be consistently indented and left-aligned. The first body element within a footnote may often begin on the same line as the footnote label. However, if the first element fits on one line and the indentation of the remaining elements differ, the first element must begin on the line after the footnote label. -Otherwise, the difference in indentation will not be detected.Footnotes may occur anywhere in the document, not only at -the end. Where and how they appear in the processed output depends on the processing system.Here is a manually numbered -footnote: +Otherwise, the difference in indentation will not be detected. + +Footnotes may occur anywhere in the document, not only at the end. Where and how they appear in the processed output +depends on the processing system. +Here is a manually numbered footnote: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ .. [1] Body elements go here. └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ @@ -1215,10 +1244,10 @@ reference. For example: If [#note]_ is the first footnote reference, it will show up as "[1]". We can refer to it again as [#note]_ and again see "[1]". We can also refer to it as note_ (an ordinary internal hyperlink reference). .. [#note] This is the footnote labeled "note". + The numbering is determined by the order of the footnotes, not by the order of the references. For footnote references without autonumber labels ([#]_), the footnotes and footnote references must be in the same relative order but need not alternate in lock-step. For example: - ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ [#]_ is a reference to footnote 1, and [#]_ is a reference to footnote 2. @@ -1258,8 +1287,10 @@ heart suit ("&hearts;"/U+02665) diamond suit ("&diams;"/U+02666) club suit ("&clubs;"/U+02663) + If more than ten symbols are required, the same sequence will be reused, doubled and then tripled, and so on ("**" etc.). + ╭─────────────────────────────────────────────────────── Note: ───────────────────────────────────────────────────────╮ │ When using auto-symbol footnotes, the choice of output encoding is important. Many of the symbols used are not │ │ encodable in certain common text encodings such as Latin-1 (ISO 8859-1). The use of UTF-8 for the output encoding │ @@ -1369,13 +1400,17 @@ the lines are joined with whitespace before being normalized. For example, the following indirect hyperlink targets are equivalent: .. _one-liner: `A HYPERLINK`_ .. _entirely-below: `a hyperlink`_ .. _split: `A Hyperlink`_ It is possible to include an alias directly within hyperlink references. See Embedded URIs and Aliases below. + If the reference name contains any colons, either: + the phrase must be enclosed in backquotes: .. _`FAQTS: Computers: Programming: Languages: Python`: http://python.faqts.com/ or the colon(s) must be backslash-escaped in the link target: .. _Chapter One\: "Tadpole Days": It's not easy being green... -See Implicit Hyperlink Targets below for the resolution of duplicate reference names.Syntax diagram: +See Implicit Hyperlink Targets below for the resolution of duplicate reference names. + +Syntax diagram: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ +-------+----------------------+ | ".. " | "_" name ":" link | @@ -1449,18 +1484,20 @@ If an implementation of reStructuredText does not recognize a directive (i.e., the directive-handler is not installed a level-3 (error) system message is generated, and the entire directive block (including the directive itself) will be included as a literal block. Thus "::" is a natural choice. + The directive block consists of any text on the first line of the directive after the directive marker, and any subsequent indented text. The interpretation of the directive block is up to the directive code. There are three logical parts to the directive block: + 1 Directive arguments. 2 Directive options. 3 Directive content. + Individual directives can employ any combination of these parts. Directive arguments can be filesystem paths, URLs, title text, etc. Directive options are indicated using field lists; the field names and contents are directive-specific. Arguments and options must form a contiguous block beginning on the first or second line of the directive; a blank line indicates the beginning of the directive content block. If either arguments and/or options are employed by the directive, a blank line must separate them from the directive content. The "figure" directive employs all three parts: - ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ .. figure:: larch.png :scale: 50 @@ -1648,9 +1685,12 @@ 3 Duplicate explicit hyperlink targets are removed, and level-2 (warning) system messages are inserted. Exception: duplicate external hyperlink targets (identical hyperlink names and referenced URIs) do not conflict, and are not removed. -System messages are inserted where target links have been removed. See "Error Handling" in PEP 258.The parser must -return a set of unique hyperlink targets. The calling software (such as the Docutils) can warn of unresolvable links, -giving reasons for the messages. + +System messages are inserted where target links have been removed. See "Error Handling" in PEP 258. + +The parser must return a set of unique hyperlink targets. The calling software (such as the Docutils) can warn of +unresolvable links, giving reasons for the messages. + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Inline Markup ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -1667,11 +1707,17 @@ interpreted text: "`" inline literals: "``" substitution references: "|" + Three constructs use different start-strings and end-strings: + inline internal targets: "_`" and "`" footnote references: "[" and "]_" hyperlink references: "`" and "`_" (phrases), or just a trailing "_" (single words) -Standalone hyperlinks are recognized implicitly, and use no extra markup.Inline comments are not supported. + +Standalone hyperlinks are recognized implicitly, and use no extra markup. + +Inline comments are not supported. + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Inline markup recognition rules ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -1685,14 +1731,18 @@ 5 If an inline markup start-string is immediately preceded by one of the ASCII characters ' " < ( [ { or a similar non-ASCII character , it must not be followed by the corresponding closing character from ' " > ) ] } or a similar non-ASCII character . (For quotes, matching characters can be any of the quotation marks in international usage.) + If the configuration setting character-level-inline-markup is False (default), additional conditions apply to the characters "around" the inline markup: + 1 Inline markup start-strings must start a text block or be immediately preceded by whitespace, one of the ASCII characters - : / ' " < ( [ { or a similar non-ASCII punctuation character. 2 Inline markup end-strings must end a text block or be immediately followed by whitespace, one of the ASCII characte - . , : ; ! ? \ / ' " ) ] } > or a similar non-ASCII punctuation character. + The inline markup recognition rules were devised to allow 90% of non-markup uses of "*", "`", "_", and "|" without escaping. For example, none of the following terms are recognized as containing inline markup strings: + 2 * x a ** b (* BOM32_* ` `` _ __ | (breaks rule 1) || (breaks rule 3) "*" '|' (*) [*] {*} <*> ‘*’ ‚*‘ ‘*‚ ’*’ ‚*’ “*” „*“ “*„ ”*” „*” »*« ›*‹ «* @@ -1700,12 +1750,16 @@ <rst-document>:2564: (WARNING/2) Inline emphasis start-string without end-string. <rst-document>:2564: (WARNING/2) Inline emphasis start-string without end-string. 2*x a**b O(N**2) e**(x*y) f(x)*f(y) a|b file*.* __init__ __init__() (breaks rule 6) + No escaping is required inside the following inline markup examples: + *2 * x *a **b *.txt* (breaks rule 2; renders as "2 * x *a **b *.txt") *2*x a**b O(N**2) e**(x*y) f(x)*f(y) a*(1+2)* (breaks rule 7; renders as "2*x a**b O(N**2) e**(x*y) f(x)*f(y) a*(1+2) + It may be desirable to use inline literals for some of these anyhow, especially if they represent code snippets. It's a -judgment call.The following terms do require either literal-quoting or escaping to avoid misinterpretation: +judgment call. +The following terms do require either literal-quoting or escaping to avoid misinterpretation: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ *4, class_, *args, **kwargs, `TeX-quoted', *ML, *.txt └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ @@ -1749,10 +1803,10 @@ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ The backslashes and spaces separating "re", "Structured", and "Text" above will disappear from the processed document. -╭───────────────────────────────────────────────────── Caution: ──────────────────────────────────────────────────────╮ -│ The use of backslash-escapes for character-level inline markup is not encouraged. Such use is ugly and detrimental │ -│ to the unprocessed document's readability. Please use this feature sparingly and only where absolutely necessary. │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭───────────────────────────────────────────────────── Caution: ──────────────────────────────────────────────────────╮ +│ The use of backslash-escapes for character-level inline markup is not encouraged. Such use is ugly and detrimental │ +│ to the unprocessed document's readability. Please use this feature sparingly and only where absolutely necessary. │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Emphasis ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -1869,12 +1923,13 @@ No start-string, end-string = "__". Start-string = "`", end-string = "`__". (Phrase references.) Start-string = "`", end-string = "`__". (Phrase references.) + Hyperlink references are indicated by a trailing underscore, "_", except for standalone hyperlinks which are recognized independently. The underscore can be thought of as a right-pointing arrow. The trailing underscores point away from -hyperlink references, and the leading underscores point toward hyperlink targets.Hyperlinks consist of two parts. In -the text body, there is a source link, a reference name with a trailing underscore (or two underscores for anonymous -hyperlinks): +hyperlink references, and the leading underscores point toward hyperlink targets. +Hyperlinks consist of two parts. In the text body, there is a source link, a reference name with a trailing underscore +(or two underscores for anonymous hyperlinks): ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ See the Python_ home page for info. └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ @@ -1945,12 +2000,12 @@ See `<a_named_relative_link>`_ or `<an_anonymous_relative_link>`__ for details. └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -╭───────────────────────────────────────────────────── Caution: ──────────────────────────────────────────────────────╮ -│ This construct offers easy authoring and maintenance of hyperlinks at the expense of general readability. Inline │ -│ URIs, especially long ones, inevitably interrupt the natural flow of text. For documents meant to be read in source │ -│ form, the use of independent block-level hyperlink targets is strongly recommended. The embedded URI construct is │ -│ most suited to documents intended only to be read in processed form. │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭───────────────────────────────────────────────────── Caution: ──────────────────────────────────────────────────────╮ +│ This construct offers easy authoring and maintenance of hyperlinks at the expense of general readability. Inline │ +│ URIs, especially long ones, inevitably interrupt the natural flow of text. For documents meant to be read in source │ +│ form, the use of independent block-level hyperlink targets is strongly recommended. The embedded URI construct is │ +│ most suited to documents intended only to be read in processed form. │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Inline Internal Targets ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -1986,8 +2041,8 @@ a single "#" (denoting auto-numbered footnotes), a "#" followed by a simple reference name (an autonumber label), or a single "*" (denoting auto-symbol footnotes). -For example: +For example: ┌─────────────────────────────────────────────────────── python ───────────────────────────────────────────────────────┐ Please RTFM [1]_. @@ -2069,9 +2124,11 @@ URI, as defined in RFC2396 and RFC2732. 2 Standalone email addresses, which are treated as if they were absolute URIs with a "mailto:" scheme. Example: someone@somewhere.com + Punctuation at the end of a URI is not considered part of the URI, unless the URI is terminated by a closing angle bracket (">"). Backslashes may be used in URIs to escape markup characters, specifically asterisks ("*") and underscores ("_") which are valid URI characters (see Escaping Mechanism above). + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Units ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -2095,9 +2152,14 @@ px (pixels, 1 px = 1/96 in) pt (points; 1 pt = 1/72 in) pc (picas; 1 pc = 1/6 in = 12 pt) -This set corresponds to the length units in CSS2 (a subset of length units in CSS3).The following are all valid length -values: "1.5em", "20 mm", ".5in".Length values without unit are completed with a writer-dependent default (e.g. "px" -with HTML, "pt" with latex2e). See the writer specific documentation in the user doc for details. + +This set corresponds to the length units in CSS2 (a subset of length units in CSS3). + +The following are all valid length values: "1.5em", "20 mm", ".5in". + +Length values without unit are completed with a writer-dependent default (e.g. "px" with HTML, "pt" with latex2e). See +the writer specific documentation in the user doc for details. + ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Percentage Units ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ @@ -2110,25 +2172,25 @@ Doctree elements: system_message, problematic. Markup errors are handled according to the specification in PEP 258. -╭────────────────────────────────── System Message: INFO/1 (<rst-document>, line 5); ──────────────────────────────────╮ - <rst-document>:5: (INFO/1) Enumerated list start value not ordinal-1: "6" (ordinal 6) -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭──────────────────────────────── System Message: INFO/1 (<rst-document>, line 3197); ─────────────────────────────────╮ - <rst-document>:3197: (INFO/1) Duplicate explicit target name: "topic". -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭──────────────────────────────── System Message: INFO/1 (<rst-document>, line 3208); ─────────────────────────────────╮ - <rst-document>:3208: (INFO/1) Duplicate explicit target name: "list_item". -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭──────────────────────────────── System Message: INFO/1 (<rst-document>, line 3254); ─────────────────────────────────╮ - <rst-document>:3254: (INFO/1) Duplicate explicit target name: "reference". -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭──────────────────────────────── System Message: INFO/1 (<rst-document>, line 3255); ─────────────────────────────────╮ - <rst-document>:3255: (INFO/1) Duplicate explicit target name: "reference". -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -┌─────────────────────────────────────────────────────── Footer ───────────────────────────────────────────────────────┐ - In LaTeX, the default definition is 1 px = 1/72 in (cf. How to - configure the size of a pixel in the LaTeX writer documentation). -└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +╭────────────────────────────────── System Message: INFO/1 (<rst-document>, line 5); ──────────────────────────────────╮ + <rst-document>:5: (INFO/1) Enumerated list start value not ordinal-1: "6" (ordinal 6) +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭──────────────────────────────── System Message: INFO/1 (<rst-document>, line 3197); ─────────────────────────────────╮ + <rst-document>:3197: (INFO/1) Duplicate explicit target name: "topic". +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭──────────────────────────────── System Message: INFO/1 (<rst-document>, line 3208); ─────────────────────────────────╮ + <rst-document>:3208: (INFO/1) Duplicate explicit target name: "list_item". +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭──────────────────────────────── System Message: INFO/1 (<rst-document>, line 3254); ─────────────────────────────────╮ + <rst-document>:3254: (INFO/1) Duplicate explicit target name: "reference". +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭──────────────────────────────── System Message: INFO/1 (<rst-document>, line 3255); ─────────────────────────────────╮ + <rst-document>:3255: (INFO/1) Duplicate explicit target name: "reference". +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +┌─────────────────────────────────────────────────────── Footer ───────────────────────────────────────────────────────┐ + In LaTeX, the default definition is 1 px = 1/72 in (cf. How to + configure the size of a pixel in the LaTeX writer documentation). +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘