diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a872a390..bd82db4a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,16 @@ ##### Enhancements -* None. +* New config option "use_safe_filenames" encodes unsafe characters when + generating filenames. By default, documentation may receive filenames like + "/(_:_:).html". With "use_safe_filenames", the same file will receive the name + "_2F_28_5F_3A_5F_3A_29.html" instead. + [Jeremy David Giesbrecht](https://github.com/SDGGiesbrecht) + [#699](https://github.com/realm/jazzy/issues/699) + [#146](https://github.com/realm/jazzy/issues/146) + [#361](https://github.com/realm/jazzy/issues/361) + [#547](https://github.com/realm/jazzy/issues/547) + [#558](https://github.com/realm/jazzy/issues/558) ##### Bug Fixes diff --git a/lib/jazzy/config.rb b/lib/jazzy/config.rb index 3f974d4a4..f174ebfd6 100644 --- a/lib/jazzy/config.rb +++ b/lib/jazzy/config.rb @@ -294,6 +294,14 @@ def expand_path(path) Pathname(__FILE__).parent + 'themes' + t end + config_attr :use_safe_filenames, + command_line: '--use-safe-filenames', + description: 'Replace unsafe characters in filenames with an encoded '\ + 'representation. This will reduce human readability of '\ + 'some URLs, but may be necessary for projects that '\ + 'expose filename-unfriendly functions such as /(_:_:)', + default: false + config_attr :template_directory, command_line: ['-t', '--template-directory DIRPATH'], description: 'DEPRECATED: Use --theme instead.', diff --git a/lib/jazzy/sourcekitten.rb b/lib/jazzy/sourcekitten.rb index d6bb2968b..c16a099a0 100644 --- a/lib/jazzy/sourcekitten.rb +++ b/lib/jazzy/sourcekitten.rb @@ -63,6 +63,15 @@ def self.make_group(group, name, abstract) end unless group.empty? end + def self.sanitize_filename(unsafe_filename) + if Config.instance.use_safe_filenames + normalized = unsafe_filename.unicode_normalize(:nfc) + return CGI.escape(normalized).gsub('_', '%5F').tr('%', '_') + else + return unsafe_filename + end + end + # rubocop:disable Metrics/MethodLength # Generate doc URL by prepending its parents URLs # @return [Hash] input docs with URLs @@ -72,7 +81,7 @@ def self.make_doc_urls(docs) # Create HTML page for this doc if it has children or is root-level doc.url = ( subdir_for_doc(doc) + - [doc.name + '.html'] + [sanitize_filename(doc.name) + '.html'] ).join('/') doc.children = make_doc_urls(doc.children) else