diff --git a/doc/development/gitlab_flavored_markdown/specification_guide/index.md b/doc/development/gitlab_flavored_markdown/specification_guide/index.md
index 4a6a1d8f64fea89a0cf6eb43966462556d0e8131..b1ab39b03214811a48b65d3db9343a092fa8685b 100644
--- a/doc/development/gitlab_flavored_markdown/specification_guide/index.md
+++ b/doc/development/gitlab_flavored_markdown/specification_guide/index.md
@@ -86,7 +86,7 @@ Some places in the code refer to both the GitLab and GitHub specifications
 simultaneous in the same areas of logic. In these situations,
 _GitHub_ Flavored Markdown may be referred to with variable or constant names like
 `ghfm_` to avoid confusion. For example, we use the `ghfm` acronym for the
-[`ghfm_spec_v_0.29.txt` GitHub Flavored Markdown specification file](#github-flavored-markdown-specification)
+[`ghfm_spec_v_0.29.md` GitHub Flavored Markdown specification file](#github-flavored-markdown-specification),
 which is committed to the `gitlab` repository and used as input to the
 [`update_specification.rb` script](#update-specificationrb-script).
 
@@ -618,8 +618,8 @@ subgraph script:
   A --> B{Backend Markdown API}
 end
 subgraph input:<br/>input specification files
-  C[ghfm_spec_v_0.29.txt] --> A
-  D[glfm_intro.txt] --> A
+  C[ghfm_spec_v_0.29.md] --> A
+  D[glfm_intro.md] --> A
   E[glfm_official_specification_examples.md] --> A
   F[glfm_internal_extension_examples.md] --> A
 end
@@ -749,7 +749,7 @@ subcategories based on their usage and purpose:
     These are the original input to drive all other automated GLFM
     specification scripts, processes, or tests.
     - `github_flavored_markdown`: Contains only the downloaded and committed
-      [`ghfm_spec_v_0.29.txt`](#github-flavored-markdown-specification) specification.
+      [`ghfm_spec_v_0.29.md`](#github-flavored-markdown-specification) specification.
     - `gitlab_flavored_markdown`: Contains all `glfm_*` files.
       - `*.md` [input specification files](#input-specification-files),
         which represent the GLFM specification itself.
@@ -769,19 +769,20 @@ See the main [specification files](#specification-files) section for more contex
 
 ##### GitHub Flavored Markdown specification
 
-[`glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt)
-is the official latest [GFM `spec.txt`](https://github.com/github/cmark-gfm/blob/master/test/spec.txt).
+[`glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md)
+is a copy of the official latest [GFM `spec.txt`](https://github.com/github/cmark-gfm/blob/master/test/spec.txt).
 
-- It is automatically downloaded and updated by `update-specification.rb` script.
+- It is automatically downloaded and updated by the `update-specification.rb` script.
 - When it is downloaded, the version number is added to the filename.
+- The extension is changed from `*.txt` to `*.md` so that it can be handled better by Markdown editors.
 
 NOTE:
 For extra clarity, this file uses the `ghfm` acronym in its name instead of `gfm`, as
 explained in the [Acronyms section](#acronyms-glfm-ghfm-gfm-commonmark).
 
-##### `glfm_intro.txt`
+##### `glfm_intro.md`
 
-[`glfm_specification/input/gitlab_flavored_markdown/glfm_intro.txt`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/gitlab_flavored_markdown/glfm_intro.txt)
+[`glfm_specification/input/gitlab_flavored_markdown/glfm_intro.md`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/gitlab_flavored_markdown/glfm_intro.md)
 is the GitLab-specific version of the prose in the introduction section of the GLFM specification.
 
 - It is manually updated.
diff --git a/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt b/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md
similarity index 99%
rename from glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt
rename to glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md
index 582131d700a42830dcbc46dc4baebbe2f347f4e8..1702761563ec48c004d27abcacec5734ed1756f8 100644
--- a/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt
+++ b/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md
@@ -2077,7 +2077,7 @@ followed by one of the strings (case-insensitive) `address`,
 `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `head`, `header`, `hr`,
 `html`, `iframe`, `legend`, `li`, `link`, `main`, `menu`, `menuitem`,
 `nav`, `noframes`, `ol`, `optgroup`, `option`, `p`, `param`,
-`section`, `source`, `summary`, `table`, `tbody`, `td`,
+`section`, `summary`, `table`, `tbody`, `td`,
 `tfoot`, `th`, `thead`, `title`, `tr`, `track`, `ul`, followed
 by [whitespace], the end of the line, the string `>`, or
 the string `/>`.\
@@ -10224,4 +10224,3 @@ closers:
 
 After we're done, we remove all delimiters above `stack_bottom` from the
 delimiter stack.
-
diff --git a/glfm_specification/input/gitlab_flavored_markdown/glfm_intro.txt b/glfm_specification/input/gitlab_flavored_markdown/glfm_intro.md
similarity index 100%
rename from glfm_specification/input/gitlab_flavored_markdown/glfm_intro.txt
rename to glfm_specification/input/gitlab_flavored_markdown/glfm_intro.md
diff --git a/glfm_specification/output/spec.txt b/glfm_specification/output/spec.txt
index af4eba06758ddee6d0d291183a445cd95defd289..9fa6c4c291e62c6b9951e9d0e9a25e16db5d9bb3 100644
--- a/glfm_specification/output/spec.txt
+++ b/glfm_specification/output/spec.txt
@@ -1791,7 +1791,7 @@ followed by one of the strings (case-insensitive) `address`,
 `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `head`, `header`, `hr`,
 `html`, `iframe`, `legend`, `li`, `link`, `main`, `menu`, `menuitem`,
 `nav`, `noframes`, `ol`, `optgroup`, `option`, `p`, `param`,
-`section`, `source`, `summary`, `table`, `tbody`, `td`,
+`section`, `summary`, `table`, `tbody`, `td`,
 `tfoot`, `th`, `thead`, `title`, `tr`, `track`, `ul`, followed
 by [whitespace], the end of the line, the string `>`, or
 the string `/>`.\
@@ -10328,4 +10328,3 @@ closers:
 
 After we're done, we remove all delimiters above `stack_bottom` from the
 delimiter stack.
-
diff --git a/scripts/lib/glfm/constants.rb b/scripts/lib/glfm/constants.rb
index e5790bbdd8831621e0dcdef75b4cefd9b694d461..27b959cd135cca6d85bc140f70089d7a9840d543 100644
--- a/scripts/lib/glfm/constants.rb
+++ b/scripts/lib/glfm/constants.rb
@@ -10,12 +10,12 @@ module Constants
     # GitHub Flavored Markdown specification file
     GHFM_SPEC_TXT_URI = 'https://raw.githubusercontent.com/github/cmark-gfm/master/test/spec.txt'
     GHFM_SPEC_VERSION = '0.29'
-    GHFM_SPEC_TXT_FILENAME = "ghfm_spec_v_#{GHFM_SPEC_VERSION}.txt"
-    GHFM_SPEC_TXT_PATH = specification_path.join('input/github_flavored_markdown', GHFM_SPEC_TXT_FILENAME)
+    GHFM_SPEC_MD_FILENAME = "ghfm_spec_v_#{GHFM_SPEC_VERSION}.md"
+    GHFM_SPEC_MD_PATH = specification_path.join('input/github_flavored_markdown', GHFM_SPEC_MD_FILENAME)
 
     # GitLab Flavored Markdown specification files
     specification_input_glfm_path = specification_path.join('input/gitlab_flavored_markdown')
-    GLFM_INTRO_TXT_PATH = specification_input_glfm_path.join('glfm_intro.txt')
+    GLFM_INTRO_MD_PATH = specification_input_glfm_path.join('glfm_intro.md')
     GLFM_EXAMPLES_TXT_PATH = specification_input_glfm_path.join('glfm_canonical_examples.txt')
     GLFM_EXAMPLE_STATUS_YML_PATH = specification_input_glfm_path.join('glfm_example_status.yml')
     GLFM_EXAMPLE_METADATA_YML_PATH =
diff --git a/scripts/lib/glfm/update_specification.rb b/scripts/lib/glfm/update_specification.rb
index 73c23d40de5b16ccda723f20b7da056d35bd8d0e..7a89797123b284477a4c0ce632f12ae988e41ffe 100644
--- a/scripts/lib/glfm/update_specification.rb
+++ b/scripts/lib/glfm/update_specification.rb
@@ -12,16 +12,16 @@ class UpdateSpecification
 
     def process
       output('Updating specification...')
-      ghfm_spec_txt_lines = load_ghfm_spec_txt
-      glfm_spec_txt_string = build_glfm_spec_txt(ghfm_spec_txt_lines)
+      ghfm_spec_lines = load_ghfm_spec
+      glfm_spec_txt_string = build_glfm_spec_txt(ghfm_spec_lines)
       write_glfm_spec_txt(glfm_spec_txt_string)
     end
 
     private
 
-    def load_ghfm_spec_txt
+    def load_ghfm_spec
       # We only re-download the GitHub Flavored Markdown specification if the
-      # UPDATE_GHFM_SPEC_TXT environment variable is set to true, which should only
+      # UPDATE_GHFM_SPEC_MD environment variable is set to true, which should only
       # ever be done manually and locally, never in CI. This provides some security
       # protection against a possible injection attack vector, if the GitHub-hosted
       # version of the spec is ever temporarily compromised with an injection attack.
@@ -29,40 +29,40 @@ def load_ghfm_spec_txt
       # This also avoids doing external network access to download the file
       # in CI jobs, which can avoid potentially flaky builds if the GitHub-hosted
       # version of the file is temporarily unavailable.
-      if ENV['UPDATE_GHFM_SPEC_TXT'] == 'true'
-        download_and_write_ghfm_spec_txt
+      if ENV['UPDATE_GHFM_SPEC_MD'] == 'true'
+        update_ghfm_spec_md
       else
-        read_existing_ghfm_spec_txt
+        read_existing_ghfm_spec_md
       end
     end
 
-    def read_existing_ghfm_spec_txt
-      output("Reading existing #{GHFM_SPEC_TXT_PATH}...")
-      File.open(GHFM_SPEC_TXT_PATH).readlines
+    def read_existing_ghfm_spec_md
+      output("Reading existing #{GHFM_SPEC_MD_PATH}...")
+      File.open(GHFM_SPEC_MD_PATH).readlines
     end
 
-    def download_and_write_ghfm_spec_txt
+    def update_ghfm_spec_md
       output("Downloading #{GHFM_SPEC_TXT_URI}...")
       ghfm_spec_txt_uri_io = URI.open(GHFM_SPEC_TXT_URI)
 
       # Read IO stream into an array of lines for easy processing later
-      ghfm_spec_txt_lines = ghfm_spec_txt_uri_io.readlines
-      raise "Unable to read lines from #{GHFM_SPEC_TXT_URI}" if ghfm_spec_txt_lines.empty?
+      ghfm_spec_lines = ghfm_spec_txt_uri_io.readlines
+      raise "Unable to read lines from #{GHFM_SPEC_TXT_URI}" if ghfm_spec_lines.empty?
 
       # Make sure the GHFM spec version has not changed
-      validate_expected_spec_version!(ghfm_spec_txt_lines[2])
+      validate_expected_spec_version!(ghfm_spec_lines[2])
 
       # Reset IO stream and re-read into a single string for easy writing
       # noinspection RubyNilAnalysis
       ghfm_spec_txt_uri_io.seek(0)
-      ghfm_spec_txt_string = ghfm_spec_txt_uri_io.read
-      raise "Unable to read string from #{GHFM_SPEC_TXT_URI}" unless ghfm_spec_txt_string
+      ghfm_spec_string = ghfm_spec_txt_uri_io.read
+      raise "Unable to read string from #{GHFM_SPEC_TXT_URI}" unless ghfm_spec_string
 
-      output("Writing #{GHFM_SPEC_TXT_PATH}...")
-      GHFM_SPEC_TXT_PATH.dirname.mkpath
-      write_file(GHFM_SPEC_TXT_PATH, ghfm_spec_txt_string)
+      output("Writing #{GHFM_SPEC_MD_PATH}...")
+      GHFM_SPEC_MD_PATH.dirname.mkpath
+      write_file(GHFM_SPEC_MD_PATH, ghfm_spec_string)
 
-      ghfm_spec_txt_lines
+      ghfm_spec_lines
     end
 
     def validate_expected_spec_version!(version_line)
@@ -85,13 +85,13 @@ def replace_header(spec_txt_lines)
     end
 
     def replace_intro_section(spec_txt_lines)
-      glfm_intro_txt_lines = File.open(GLFM_INTRO_TXT_PATH).readlines
-      raise "Unable to read lines from #{GLFM_INTRO_TXT_PATH}" if glfm_intro_txt_lines.empty?
+      glfm_intro_md_lines = File.open(GLFM_INTRO_MD_PATH).readlines
+      raise "Unable to read lines from #{GLFM_INTRO_MD_PATH}" if glfm_intro_md_lines.empty?
 
       ghfm_intro_header_begin_index = spec_txt_lines.index do |line|
         line =~ INTRODUCTION_HEADER_LINE_TEXT
       end
-      raise "Unable to locate introduction header line in #{GHFM_SPEC_TXT_PATH}" if ghfm_intro_header_begin_index.nil?
+      raise "Unable to locate introduction header line in #{GHFM_SPEC_MD_PATH}" if ghfm_intro_header_begin_index.nil?
 
       # Find the index of the next header after the introduction header, starting from the index
       # of the introduction header this is the length of the intro section
@@ -100,7 +100,7 @@ def replace_intro_section(spec_txt_lines)
       end
 
       # Replace the intro section with the GitLab flavored Markdown intro section
-      spec_txt_lines[ghfm_intro_header_begin_index, ghfm_intro_section_length] = glfm_intro_txt_lines
+      spec_txt_lines[ghfm_intro_header_begin_index, ghfm_intro_section_length] = glfm_intro_md_lines
     end
 
     def insert_examples_txt(spec_txt_lines)
@@ -110,7 +110,7 @@ def insert_examples_txt(spec_txt_lines)
       ghfm_end_tests_comment_index = spec_txt_lines.index do |line|
         line =~ END_TESTS_COMMENT_LINE_TEXT
       end
-      raise "Unable to locate 'END TESTS' comment line in #{GHFM_SPEC_TXT_PATH}" if ghfm_end_tests_comment_index.nil?
+      raise "Unable to locate 'END TESTS' comment line in #{GHFM_SPEC_MD_PATH}" if ghfm_end_tests_comment_index.nil?
 
       # Insert the GLFM examples before the 'END TESTS' comment line
       spec_txt_lines[ghfm_end_tests_comment_index - 1] = ["\n", glfm_examples_txt_lines, "\n"].flatten
diff --git a/spec/scripts/lib/glfm/update_specification_spec.rb b/spec/scripts/lib/glfm/update_specification_spec.rb
index 9fb671e0016a1076923681b89339cda9ff7ef22a..1cdc90876de94a49d3685dc1813276d7ef06f068 100644
--- a/spec/scripts/lib/glfm/update_specification_spec.rb
+++ b/spec/scripts/lib/glfm/update_specification_spec.rb
@@ -7,11 +7,11 @@
 
   let(:ghfm_spec_txt_uri) { described_class::GHFM_SPEC_TXT_URI }
   let(:ghfm_spec_txt_uri_io) { StringIO.new(ghfm_spec_txt_contents) }
-  let(:ghfm_spec_txt_path) { described_class::GHFM_SPEC_TXT_PATH }
+  let(:ghfm_spec_md_path) { described_class::GHFM_SPEC_MD_PATH }
   let(:ghfm_spec_txt_local_io) { StringIO.new(ghfm_spec_txt_contents) }
 
-  let(:glfm_intro_txt_path) { described_class::GLFM_INTRO_TXT_PATH }
-  let(:glfm_intro_txt_io) { StringIO.new(glfm_intro_txt_contents) }
+  let(:glfm_intro_md_path) { described_class::GLFM_INTRO_MD_PATH }
+  let(:glfm_intro_md_io) { StringIO.new(glfm_intro_md_contents) }
   let(:glfm_examples_txt_path) { described_class::GLFM_EXAMPLES_TXT_PATH }
   let(:glfm_examples_txt_io) { StringIO.new(glfm_examples_txt_contents) }
   let(:glfm_spec_txt_path) { described_class::GLFM_SPEC_TXT_PATH }
@@ -52,7 +52,7 @@
     MARKDOWN
   end
 
-  let(:glfm_intro_txt_contents) do
+  let(:glfm_intro_md_contents) do
     # language=Markdown
     <<~MARKDOWN
       # Introduction
@@ -73,15 +73,15 @@
 
   before do
     # Mock default ENV var values
-    allow(ENV).to receive(:[]).with('UPDATE_GHFM_SPEC_TXT').and_return(nil)
+    allow(ENV).to receive(:[]).with('UPDATE_GHFM_SPEC_MD').and_return(nil)
     allow(ENV).to receive(:[]).and_call_original
 
     # We mock out the URI and local file IO objects with real StringIO, instead of just mock
     # objects. This gives better and more realistic coverage, while still avoiding
     # actual network and filesystem I/O during the spec run.
     allow(URI).to receive(:open).with(ghfm_spec_txt_uri) { ghfm_spec_txt_uri_io }
-    allow(File).to receive(:open).with(ghfm_spec_txt_path) { ghfm_spec_txt_local_io }
-    allow(File).to receive(:open).with(glfm_intro_txt_path) { glfm_intro_txt_io }
+    allow(File).to receive(:open).with(ghfm_spec_md_path) { ghfm_spec_txt_local_io }
+    allow(File).to receive(:open).with(glfm_intro_md_path) { glfm_intro_md_io }
     allow(File).to receive(:open).with(glfm_examples_txt_path) { glfm_examples_txt_io }
     allow(File).to receive(:open).with(glfm_spec_txt_path, 'w') { glfm_spec_txt_io }
 
@@ -90,7 +90,7 @@
   end
 
   describe 'retrieving latest GHFM spec.txt' do
-    context 'when UPDATE_GHFM_SPEC_TXT is not true (default)' do
+    context 'when UPDATE_GHFM_SPEC_MD is not true (default)' do
       it 'does not download' do
         expect(URI).not_to receive(:open).with(ghfm_spec_txt_uri)
 
@@ -100,12 +100,12 @@
       end
     end
 
-    context 'when UPDATE_GHFM_SPEC_TXT is true' do
+    context 'when UPDATE_GHFM_SPEC_MD is true' do
       let(:ghfm_spec_txt_local_io) { StringIO.new }
 
       before do
-        allow(ENV).to receive(:[]).with('UPDATE_GHFM_SPEC_TXT').and_return('true')
-        allow(File).to receive(:open).with(ghfm_spec_txt_path, 'w') { ghfm_spec_txt_local_io }
+        allow(ENV).to receive(:[]).with('UPDATE_GHFM_SPEC_MD').and_return('true')
+        allow(File).to receive(:open).with(ghfm_spec_md_path, 'w') { ghfm_spec_txt_local_io }
       end
 
       context 'with success' do
@@ -170,7 +170,7 @@
 
     it 'replaces the intro section with the GitLab version' do
       expect(glfm_contents).not_to match(/What is GitHub Flavored Markdown/m)
-      expect(glfm_contents).to match(/#{Regexp.escape(glfm_intro_txt_contents)}/m)
+      expect(glfm_contents).to match(/#{Regexp.escape(glfm_intro_md_contents)}/m)
     end
 
     it 'inserts the GitLab examples sections before the appendix section' do