@@ -184,13 +184,7 @@ pub fn generate_html<IO: FileSystemReader>(
184184 content : Content :: Text ( temp. render ( ) . expect ( "Page template rendering" ) ) ,
185185 } ) ;
186186
187- search_items. push ( SearchItem {
188- type_ : SearchItemType :: Page ,
189- parent_title : config. name . to_string ( ) ,
190- title : config. name . to_string ( ) ,
191- content : escape_html_content ( content) ,
192- reference : page. path . to_string ( ) ,
193- } )
187+ search_items. push ( search_item_for_page ( & config. name , & page. path , content) )
194188 }
195189
196190 // Generate module documentation pages
@@ -203,7 +197,7 @@ pub fn generate_html<IO: FileSystemReader>(
203197
204198 let documentation_content = module. ast . documentation . iter ( ) . join ( "\n " ) ;
205199 let rendered_documentation =
206- render_markdown ( & documentation_content. clone ( ) , MarkdownSource :: Comment ) ;
200+ render_markdown ( & documentation_content, MarkdownSource :: Comment ) ;
207201
208202 let mut printer = Printer :: new (
209203 module. ast . type_info . package . clone ( ) ,
@@ -215,62 +209,14 @@ pub fn generate_html<IO: FileSystemReader>(
215209 let types = printer. type_definitions ( & source_links, & module. ast . definitions ) ;
216210 let values = printer. value_definitions ( & source_links, & module. ast . definitions ) ;
217211
218- types. iter ( ) . for_each ( |type_| {
219- let constructors = type_
220- . constructors
221- . iter ( )
222- . map ( |constructor| {
223- let arguments = constructor
224- . arguments
225- . iter ( )
226- . map ( |argument| {
227- format ! ( "{}\n {}" , argument. name, argument. text_documentation)
228- } )
229- . join ( "\n " ) ;
230-
231- format ! (
232- "{}\n {}\n {}" ,
233- constructor. raw_definition, constructor. text_documentation, arguments
234- )
235- } )
236- . join ( "\n " ) ;
237-
238- search_items. push ( SearchItem {
239- type_ : SearchItemType :: Type ,
240- parent_title : module. name . to_string ( ) ,
241- title : type_. name . to_string ( ) ,
242- content : format ! (
243- "{}\n {}\n {}\n {}" ,
244- type_. raw_definition,
245- type_. text_documentation,
246- constructors,
247- import_synonyms( & module. name, type_. name)
248- ) ,
249- reference : format ! ( "{}.html#{}" , module. name, type_. name) ,
250- } )
251- } ) ;
252- values. iter ( ) . for_each ( |value| {
253- search_items. push ( SearchItem {
254- type_ : SearchItemType :: Value ,
255- parent_title : module. name . to_string ( ) ,
256- title : value. name . to_string ( ) ,
257- content : format ! (
258- "{}\n {}\n {}" ,
259- value. raw_definition,
260- value. text_documentation,
261- import_synonyms( & module. name, value. name)
262- ) ,
263- reference : format ! ( "{}.html#{}" , module. name, value. name) ,
264- } )
265- } ) ;
212+ types
213+ . iter ( )
214+ . for_each ( |type_| search_items. push ( search_item_for_type ( & module. name , type_) ) ) ;
215+ values
216+ . iter ( )
217+ . for_each ( |value| search_items. push ( search_item_for_value ( & module. name , value) ) ) ;
266218
267- search_items. push ( SearchItem {
268- type_ : SearchItemType :: Module ,
269- parent_title : module. name . to_string ( ) ,
270- title : module. name . to_string ( ) ,
271- content : documentation_content,
272- reference : format ! ( "{}.html" , module. name) ,
273- } ) ;
219+ search_items. push ( search_item_for_module ( module) ) ;
274220
275221 let page_title = format ! ( "{} · {} · v{}" , name, config. name, config. version) ;
276222 let page_meta_description = "" ;
@@ -472,6 +418,74 @@ pub fn generate_html<IO: FileSystemReader>(
472418 files
473419}
474420
421+ fn search_item_for_page ( package : & str , path : & str , content : String ) -> SearchItem {
422+ SearchItem {
423+ type_ : SearchItemType :: Page ,
424+ parent_title : package. to_string ( ) ,
425+ title : package. to_string ( ) ,
426+ content,
427+ reference : path. to_string ( ) ,
428+ }
429+ }
430+
431+ fn search_item_for_type ( module : & str , type_ : & TypeDefinition < ' _ > ) -> SearchItem {
432+ let constructors = type_
433+ . constructors
434+ . iter ( )
435+ . map ( |constructor| {
436+ let arguments = constructor
437+ . arguments
438+ . iter ( )
439+ . map ( |argument| format ! ( "{}\n {}" , argument. name, argument. text_documentation) )
440+ . join ( "\n " ) ;
441+
442+ format ! (
443+ "{}\n {}\n {}" ,
444+ constructor. raw_definition, constructor. text_documentation, arguments
445+ )
446+ } )
447+ . join ( "\n " ) ;
448+
449+ SearchItem {
450+ type_ : SearchItemType :: Type ,
451+ parent_title : module. to_string ( ) ,
452+ title : type_. name . to_string ( ) ,
453+ content : format ! (
454+ "{}\n {}\n {}\n {}" ,
455+ type_. raw_definition,
456+ type_. text_documentation,
457+ constructors,
458+ import_synonyms( module, type_. name)
459+ ) ,
460+ reference : format ! ( "{}.html#{}" , module, type_. name) ,
461+ }
462+ }
463+
464+ fn search_item_for_value ( module : & str , value : & DocsValues < ' _ > ) -> SearchItem {
465+ SearchItem {
466+ type_ : SearchItemType :: Value ,
467+ parent_title : module. to_string ( ) ,
468+ title : value. name . to_string ( ) ,
469+ content : format ! (
470+ "{}\n {}\n {}" ,
471+ value. raw_definition,
472+ value. text_documentation,
473+ import_synonyms( module, value. name)
474+ ) ,
475+ reference : format ! ( "{}.html#{}" , module, value. name) ,
476+ }
477+ }
478+
479+ fn search_item_for_module ( module : & Module ) -> SearchItem {
480+ SearchItem {
481+ type_ : SearchItemType :: Module ,
482+ parent_title : module. name . to_string ( ) ,
483+ title : module. name . to_string ( ) ,
484+ content : module. ast . documentation . iter ( ) . join ( "\n " ) ,
485+ reference : format ! ( "{}.html" , module. name) ,
486+ }
487+ }
488+
475489pub fn generate_json_package_interface (
476490 path : Utf8PathBuf ,
477491 package : & Package ,
@@ -529,22 +543,6 @@ fn page_unnest_test() {
529543 assert_eq ! ( page_unnest( "gleam/string/inspect" ) , "../.." ) ;
530544}
531545
532- fn escape_html_content ( it : String ) -> String {
533- it. replace ( '&' , "&" )
534- . replace ( '<' , "<" )
535- . replace ( '>' , ">" )
536- . replace ( '\"' , """ )
537- . replace ( '\'' , "'" )
538- }
539-
540- #[ test]
541- fn escape_html_content_test ( ) {
542- assert_eq ! (
543- escape_html_content( "&<>\" '" . to_string( ) ) ,
544- "&<>"'"
545- ) ;
546- }
547-
548546fn import_synonyms ( parent : & str , child : & str ) -> String {
549547 format ! ( "Synonyms:\n {parent}.{child}\n {parent} {child}" )
550548}
@@ -677,22 +675,32 @@ struct ModuleTemplate<'a> {
677675 rendering_timestamp : & ' a str ,
678676}
679677
678+ /// Search data for use by Hexdocs search, as well as the search built-in to
679+ /// generated documentation
680680#[ derive( Serialize , PartialEq , Eq , PartialOrd , Ord , Clone ) ]
681681struct SearchData {
682682 items : Vec < SearchItem > ,
683683 #[ serde( rename = "proglang" ) ]
684684 programming_language : SearchProgrammingLanguage ,
685685}
686686
687+ /// A single item that can appear as a search result
687688#[ derive( Serialize , PartialEq , Eq , PartialOrd , Ord , Clone ) ]
688689struct SearchItem {
690+ /// The type of item this is: Value, Type, Module, or other Page
689691 #[ serde( rename = "type" ) ]
690692 type_ : SearchItemType ,
693+ /// The title of the module or package containing this search item
691694 #[ serde( rename = "parentTitle" ) ]
692695 parent_title : String ,
696+ /// The title of this item
693697 title : String ,
698+ /// Markdown text which describes this item, containing documentation from
699+ /// doc comments, as well as rendered definitions of types and values.
694700 #[ serde( rename = "doc" ) ]
695701 content : String ,
702+ /// The relative URL to the documentation for this search item, for example
703+ /// `gleam/option.html#Option`
696704 #[ serde( rename = "ref" ) ]
697705 reference : String ,
698706}
0 commit comments