diff --git a/doc/Comments.autodoc b/doc/Comments.autodoc index ffa14a20..f9aa783e 100644 --- a/doc/Comments.autodoc +++ b/doc/Comments.autodoc @@ -26,7 +26,7 @@ Inside of &AutoDoc; comments, &AutoDoc; commands starting with @ can be used to control the output &AutoDoc; produces. Any comment line that does not start with an &AutoDoc; command is treated as regular documentation text and may contain (almost) arbitrary &GAPDoc; XML -markup, such as <Ref>, <A>, <List>, and similar tags. +markup, such as ``, ``, ``, and similar tags. This lets you use the normal &GAPDoc; formatting toolbox directly inside &AutoDoc; comments. @@ -287,7 +287,7 @@ first entry in the group. See for more information. @Index "@BeginExample" `@BeginExample` @Index "@EndExample" `@EndExample` @BeginExample marks the start of an example to be put into the manual. -It differs from &GAPDoc;'s <Example> (see ), +It differs from &GAPDoc;'s `` (see ), in that it expects actual code (not in a comment) interspersed with comments, to allow for examples files that can be both executed by &GAP;, and parsed by &AutoDoc;. To achieve this, &GAP; commands are not preceded by a comment, @@ -323,7 +323,7 @@ Section ). @Index "@EndExampleSession" `@EndExampleSession` @BeginExampleSession marks the start of an example to be put into the manual, while @EndExampleSession ends the example block. -It is the direct analog of &GAPDoc;'s <Example> (see ). +It is the direct analog of &GAPDoc;'s `` (see ). To illustrate this command, consider this input: ```@listing @@ -368,7 +368,7 @@ The &AutoDoc; command @Log is an alias of @BeginLog. @Index "@EndLogSession" `@EndLogSession` Works just like the @BeginExampleSession command, but the example will not be tested if manual examples are run. It is the direct analog of -&GAPDoc;'s <Log> (see ). +&GAPDoc;'s `` (see ). The &AutoDoc; command @LogSession is an alias of @BeginLogSession. @Subsection @DoNotReadRestOfFile @@ -483,7 +483,7 @@ in the HTML and text versions of the manual or worksheet, but not in the PDF ver @Index "@Index" @Index key [entry text] Adds an index entry to the current documentation text. The command @Index key entry text generates -<Index Key="key">entry text</Index>. +`entry text`. If no entry text is provided, then the entry text is empty. To use keys containing spaces, wrap the key in double quotes, e.g. @Index "my key" entry text. @@ -589,7 +589,7 @@ written in .autodoc format. @Subsection First Subsection This text belongs directly to the manual chapter. -It can use XML tags such as arg or <Ref ...>. +It can use XML tags such as arg or . @BeginExampleSession gap> S5 := SymmetricGroup(5); @@ -792,7 +792,7 @@ One can insert verbatim code blocks by placing the code between lines fence may optionally be followed by an info string. The values @listing, @example, and @log select the corresponding GAPDoc element; any other value is currently ignored. If nothing is specified - the default is to generate <Listing>. Example: + the default is to generate ``. Example: ````@listing #! ```@listing diff --git a/doc/Tutorials.autodoc b/doc/Tutorials.autodoc index 19361b6a..3abd2a01 100644 --- a/doc/Tutorials.autodoc +++ b/doc/Tutorials.autodoc @@ -132,7 +132,7 @@ DeclareOperation( "ToricVariety", [ IsConvexObject ] ); In these comment lines, you can freely use normal &GAPDoc; XML markup (with the usual exceptions for lines starting with @, which are interpreted as &AutoDoc; commands). So, for instance, tags like -<Ref>, <A>, <K>, <List>, etc. can be written +``, ``, ``, ``, etc. can be written directly in #! comment text. For chapter text, tutorial material, worked examples, and similar prose, some @@ -511,27 +511,27 @@ of the package info record are taken into account: PackageName -This is used to set the <Title> element of the +This is used to set the `` element of the title page. </Item> <Mark>Subtitle</Mark><Item> -This is used to set the <C><Subtitle></C> element of the +This is used to set the `<Subtitle>` element of the title page. </Item> <Mark>Version</Mark><Item> -This is used to set the <C><Version></C> element of the +This is used to set the `<Version>` element of the title page, with the string <Q>Version </Q> prepended. </Item> <Mark>Date</Mark><Item> -This is used to set the <C><Date></C> element of the +This is used to set the `<Date>` element of the title page. </Item> <Mark>Persons</Mark><Item> -This is used to generate <C><Author></C> elements in the +This is used to generate `<Author>` elements in the generated title page. </Item> @@ -562,7 +562,7 @@ SetPackageInfo( rec( ) ) ); ``` -This inserts <C><Copyright></C> and <C><Acknowledgements></C> blocks into +This inserts `<Copyright>` and `<Acknowledgements>` blocks into the generated <F>title.xml</F>. <C>PkgInfo.AutoDoc.TitlePage</C> has exactly the same meaning as diff --git a/gap/Markdown.gd b/gap/Markdown.gd index 9e74adef..70cff486 100644 --- a/gap/Markdown.gd +++ b/gap/Markdown.gd @@ -5,5 +5,4 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -DeclareGlobalFunction( "INSERT_IN_STRING_WITH_REPLACE" ); DeclareGlobalFunction( "CONVERT_LIST_OF_STRINGS_IN_MARKDOWN_TO_GAPDOC_XML" ); diff --git a/gap/Markdown.gi b/gap/Markdown.gi index 26007aed..ae21b5cc 100644 --- a/gap/Markdown.gi +++ b/gap/Markdown.gi @@ -6,7 +6,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later ## -InstallGlobalFunction( INSERT_IN_STRING_WITH_REPLACE, +BindGlobal( "INSERT_IN_STRING_WITH_REPLACE", function( string, new_string, position, nr_letters_to_be_replaced ) return Concatenation( string{[ 1 .. position - 1 ]}, @@ -15,6 +15,70 @@ InstallGlobalFunction( INSERT_IN_STRING_WITH_REPLACE, ); end ); +## +BindGlobal( "AUTODOC_EscapeXMLTextForInlineCode", + function( string ) + local escaped_string, split_pos; + + escaped_string := ""; + while Length(string) > 0 do + split_pos := PositionProperty( string, c -> c in "&\"<>" ); + if split_pos = fail then + Append( escaped_string, string ); + break; + fi; + if split_pos > 1 then + Append( escaped_string, string{ [ 1 .. split_pos - 1 ] } ); + fi; + if string[ split_pos ] = '&' then + Append( escaped_string, "&" ); + elif string[ split_pos ] = '"' then + Append( escaped_string, """ ); + elif string[ split_pos ] = '<' then + Append( escaped_string, "<" ); + else + Append( escaped_string, ">" ); + fi; + string := string{ [ split_pos + 1 .. Length( string ) ] }; + od; + + return escaped_string; +end ); + +## +BindGlobal( "AUTODOC_ConvertInlineBackticksInLine", + function( string, keyword_set ) + local opening_pos, closing_pos, inline_content, tag_name; + + while PositionSublist( string, "`" ) <> fail do + opening_pos := PositionSublist( string, "`" ); + closing_pos := PositionSublist( string, "`", opening_pos + 1 ); + if closing_pos = fail then + Error( "did you forget some `" ); + fi; + + if opening_pos + 1 <= closing_pos - 1 then + inline_content := string{ [ opening_pos + 1 .. closing_pos - 1 ] }; + else + inline_content := ""; + fi; + if inline_content in keyword_set then + tag_name := "Keyword"; + else + tag_name := "Code"; + fi; + string := Concatenation( + string{ [ 1 .. opening_pos - 1 ] }, + "<", tag_name, ">", + AUTODOC_EscapeXMLTextForInlineCode( inline_content ), + "</", tag_name, ">", + string{ [ closing_pos + 1 .. Length( string ) ] } + ); + od; + + return string; +end ); + ## InstallGlobalFunction( CONVERT_LIST_OF_STRINGS_IN_MARKDOWN_TO_GAPDOC_XML, function( string_list ) @@ -23,8 +87,7 @@ InstallGlobalFunction( CONVERT_LIST_OF_STRINGS_IN_MARKDOWN_TO_GAPDOC_XML, commands, position_of_command, insert, beginning_whitespaces, temp, string_list_temp, skipped, already_inserted_paragraph, in_list, in_item, converted_string_list, fence_char, fence_length, trimmed_line, code_block, info_string, - fence_element, keyword_set, opening_pos, closing_pos, inline_content, - tag_name; + fence_element, keyword_set; converted_string_list := [ ]; i := 1; @@ -94,6 +157,25 @@ InstallGlobalFunction( CONVERT_LIST_OF_STRINGS_IN_MARKDOWN_TO_GAPDOC_XML, od; string_list := converted_string_list; + # Convert inline backticks before list detection so literal tags such as + # `<List>` inside code spans do not look like structural GAPDoc tags. + keyword_set := Set( ALL_KEYWORDS() ); + skipped := false; + for i in [ 1 .. Length( string_list ) ] do + if PositionSublist( string_list[ i ], "<![CDATA[" ) <> fail then + skipped := true; + fi; + if PositionSublist( string_list[ i ], "]]>" ) <> fail then + skipped := false; + continue; + fi; + if skipped = true then + continue; + fi; + string_list[ i ] := + AUTODOC_ConvertInlineBackticksInLine( string_list[ i ], keyword_set ); + od; + ## Check for paragraphs by turning an empty string into <P/> already_inserted_paragraph := false; @@ -218,45 +300,6 @@ InstallGlobalFunction( CONVERT_LIST_OF_STRINGS_IN_MARKDOWN_TO_GAPDOC_XML, [ "$", "Math" ], [ "**", "Emph" ], [ "__", "Emph" ] ]; - keyword_set := Set( ALL_KEYWORDS() ); - - skipped := false; - for i in [ 1 .. Length( string_list ) ] do - if PositionSublist( string_list[ i ], "<![CDATA[" ) <> fail then - skipped := true; - fi; - if PositionSublist( string_list[ i ], "]]>" ) <> fail then - skipped := false; - continue; - fi; - if skipped = true then - continue; - fi; - - while PositionSublist( string_list[ i ], "`" ) <> fail do - opening_pos := PositionSublist( string_list[ i ], "`" ); - closing_pos := PositionSublist( string_list[ i ], "`", opening_pos + 1 ); - if closing_pos = fail then - Error( "did you forget some `" ); - fi; - - if opening_pos + 1 <= closing_pos - 1 then - inline_content := string_list[ i ]{ [ opening_pos + 1 .. closing_pos - 1 ] }; - else - inline_content := ""; - fi; - if inline_content in keyword_set then - tag_name := "Keyword"; - else - tag_name := "Code"; - fi; - string_list[ i ] := Concatenation( - string_list[ i ]{ [ 1 .. opening_pos - 1 ] }, - "<", tag_name, ">", inline_content, "</", tag_name, ">", - string_list[ i ]{ [ closing_pos + 1 .. Length( string_list[ i ] ) ] } - ); - od; - od; ## special handling for \$ for i in [ 1 .. Length( string_list ) ] do diff --git a/tst/manual.expected/_Chapter_Comments.xml b/tst/manual.expected/_Chapter_Comments.xml index c460bc5b..998c09cd 100644 --- a/tst/manual.expected/_Chapter_Comments.xml +++ b/tst/manual.expected/_Chapter_Comments.xml @@ -29,7 +29,7 @@ Inside of &AutoDoc; comments, <E>&AutoDoc; commands</E> starting with <C>@</C> can be used to control the output &AutoDoc; produces. Any comment line that does <E>not</E> start with an &AutoDoc; command is treated as regular documentation text and may contain (almost) arbitrary &GAPDoc; XML -markup, such as <C><Ref></C>, <C><A></C>, <C><List></C>, and similar tags. +markup, such as <Code><Ref></Code>, <Code><A></Code>, <Code><List></Code>, and similar tags. This lets you use the normal &GAPDoc; formatting toolbox directly inside &AutoDoc; comments. <P/> @@ -344,7 +344,7 @@ first entry in the group. See <Ref Sect="Section_Groups"/> for more information. <Index Key="@BeginExample"><Code>@BeginExample</Code></Index> <Index Key="@EndExample"><Code>@EndExample</Code></Index> <C>@BeginExample</C> marks the start of an example to be put into the manual. -It differs from &GAPDoc;'s <C><Example></C> (see <Ref Subsect="Log" BookName="gapdoc"/>), +It differs from &GAPDoc;'s <Code><Example></Code> (see <Ref Subsect="Log" BookName="gapdoc"/>), in that it expects actual code (not in a comment) interspersed with comments, to allow for examples files that can be both executed by &GAP;, and parsed by &AutoDoc;. To achieve this, &GAP; commands are not preceded by a comment, @@ -384,7 +384,7 @@ Section <Ref Sect="Subsection_Tut:IntegrateExisting:EverythingThere"/>). <Index Key="@EndExampleSession"><Code>@EndExampleSession</Code></Index> <C>@BeginExampleSession</C> marks the start of an example to be put into the manual, while <C>@EndExampleSession</C> ends the example block. -It is the direct analog of &GAPDoc;'s <C><Example></C> (see <Ref Subsect="Log" BookName="gapdoc"/>). +It is the direct analog of &GAPDoc;'s <Code><Example></Code> (see <Ref Subsect="Log" BookName="gapdoc"/>). <P/> To illustrate this command, consider this input: <Listing><![CDATA[ @@ -437,7 +437,7 @@ The &AutoDoc; command <C>@Log</C> is an alias of <C>@BeginLog</C>. <Index Key="@EndLogSession"><Code>@EndLogSession</Code></Index> Works just like the <C>@BeginExampleSession</C> command, but the example will not be tested if manual examples are run. It is the direct analog of -&GAPDoc;'s <C><Log></C> (see <Ref Subsect="Log" BookName="gapdoc"/>). +&GAPDoc;'s <Code><Log></Code> (see <Ref Subsect="Log" BookName="gapdoc"/>). The &AutoDoc; command <C>@LogSession</C> is an alias of <C>@BeginLogSession</C>. <P/> </Subsection> @@ -576,7 +576,7 @@ in the HTML and text versions of the manual or worksheet, but not in the PDF ver <Index Key="@Index"><C>@Index <A>key</A> [<A>entry text</A>]</C></Index> Adds an index entry to the current documentation text. The command <C>@Index key entry text</C> generates -<C><Index Key="key">entry text</Index></C>. +<Code><Index Key="key">entry text</Index></Code>. If no entry text is provided, then the entry text is empty. To use keys containing spaces, wrap the key in double quotes, e.g. <C>@Index "my key" entry text</C>. @@ -693,7 +693,7 @@ written in <F>.autodoc</F> format. @Subsection First Subsection This text belongs directly to the manual chapter. -It can use XML tags such as <A>arg</A> or <C><Ref ...></C>. +It can use XML tags such as <A>arg</A> or <Ref .../>. @BeginExampleSession gap> S5 := SymmetricGroup(5); @@ -935,7 +935,7 @@ One can insert verbatim code blocks by placing the code between lines fence may optionally be followed by an info string. The values <C>@listing</C>, <C>@example</C>, and <C>@log</C> select the corresponding GAPDoc element; any other value is currently ignored. If nothing is specified - the default is to generate <C><Listing></C>. Example: + the default is to generate <Code><Listing></Code>. Example: <P/> <Listing><![CDATA[ #! ```@listing diff --git a/tst/manual.expected/_Chapter_Tutorials.xml b/tst/manual.expected/_Chapter_Tutorials.xml index c5cb7e81..b205549f 100644 --- a/tst/manual.expected/_Chapter_Tutorials.xml +++ b/tst/manual.expected/_Chapter_Tutorials.xml @@ -152,7 +152,7 @@ DeclareOperation( "ToricVariety", [ IsConvexObject ] ); In these comment lines, you can freely use normal &GAPDoc; XML markup (with the usual exceptions for lines starting with <C>@</C>, which are interpreted as &AutoDoc; commands). So, for instance, tags like -<C><Ref></C>, <C><A></C>, <C><K></C>, <C><List></C>, etc. can be written +<Code><Ref></Code>, <Code><A></Code>, <Code><K></Code>, <Code><List></Code>, etc. can be written directly in <C>#!</C> comment text. <P/> For chapter text, tutorial material, worked examples, and similar prose, some @@ -557,23 +557,23 @@ of the package info record are taken into account: <P/> <List> <Mark>PackageName</Mark><Item> -This is used to set the <C><Title></C> element of the +This is used to set the <Code><Title></Code> element of the title page. </Item> <Mark>Subtitle</Mark><Item> -This is used to set the <C><Subtitle></C> element of the +This is used to set the <Code><Subtitle></Code> element of the title page. </Item> <Mark>Version</Mark><Item> -This is used to set the <C><Version></C> element of the +This is used to set the <Code><Version></Code> element of the title page, with the string <Q>Version </Q> prepended. </Item> <Mark>Date</Mark><Item> -This is used to set the <C><Date></C> element of the +This is used to set the <Code><Date></Code> element of the title page. </Item> <Mark>Persons</Mark><Item> -This is used to generate <C><Author></C> elements in the +This is used to generate <Code><Author></Code> elements in the generated title page. </Item> <Mark>PackageDoc</Mark><Item> @@ -602,7 +602,7 @@ SetPackageInfo( rec( ) ) ); ]]></Listing> -This inserts <C><Copyright></C> and <C><Acknowledgements></C> blocks into +This inserts <Code><Copyright></Code> and <Code><Acknowledgements></Code> blocks into the generated <F>title.xml</F>. <P/> <C>PkgInfo.AutoDoc.TitlePage</C> has exactly the same meaning as diff --git a/tst/misc.tst b/tst/misc.tst index 63ee5dde..4864b52a 100644 --- a/tst/misc.tst +++ b/tst/misc.tst @@ -122,7 +122,6 @@ gap> item!.tester_names; gap> item!.arguments; "x,y" -# # fenced code blocks in Markdown-like text # gap> CONVERT_LIST_OF_STRINGS_IN_MARKDOWN_TO_GAPDOC_XML([ @@ -195,6 +194,12 @@ gap> CONVERT_LIST_OF_STRINGS_IN_MARKDOWN_TO_GAPDOC_XML([ > "]]></Listing>" > ]; true +gap> CONVERT_LIST_OF_STRINGS_IN_MARKDOWN_TO_GAPDOC_XML([ +> "`<Log attr=\"x\"> & more`" +> ]) = [ +> "<Code><Log attr="x"> & more</Code>" +> ]; +true gap> rendered := "";; gap> stream := OutputTextString(rendered, true);; gap> SetPrintFormattingStatus(stream, false);