From fb06c44f340729a7ec5b36a563ec52b443d722a7 Mon Sep 17 00:00:00 2001 From: Maxim Reznik Date: Sat, 10 Sep 2022 10:47:13 +0300 Subject: [PATCH] Import initial sources --- .gitignore | 3 + README.md | 27 +++++- alire.toml | 17 ++++ data/.gitignore | 1 + fetch.sh | 50 ++++++++++ gnat/aqs2mdx.gpr | 18 ++++ gnat/import_style_guide_config.gpr | 49 ++++++++++ source/aqs2mdx.adb | 142 +++++++++++++++++++++++++++++ 8 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 alire.toml create mode 100644 data/.gitignore create mode 100755 fetch.sh create mode 100644 gnat/aqs2mdx.gpr create mode 100644 gnat/import_style_guide_config.gpr create mode 100644 source/aqs2mdx.adb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a30092 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/alire +/bin +/obj \ No newline at end of file diff --git a/README.md b/README.md index 48e2997..3964036 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,25 @@ -# import-style-guide -Scripts to fetch Ada Quality and Style Guide wikibook +# Scripts to fetch Ada Quality and Style Guide wikibook + +These scripts convert the WiKi book to ada-lang.io markdown. + +## Build and run + +You need `pandoc`, `curl`, `sed` installed. Build a pandoc filter with Alire: + + alr build + +Then run: + + ./fetch.sh + +## To be fixed + +* Arrange code blocks in Source Code Presentation in two columns +* Add chapter/section numbers +* Replace "see Guideline X.Y.Z{,/and X.Y.Z}", "Chapter X", "Sections X.Y" with cross links +* change definition lists? (in Portability, OOP) +* Fix Wikipedia links +* Fix examples in Reusability: + "Compare the body for the simplest version" +* Fix ACES in References +* Fix Bibliography diff --git a/alire.toml b/alire.toml new file mode 100644 index 0000000..4019e39 --- /dev/null +++ b/alire.toml @@ -0,0 +1,17 @@ +name = "import_style_guide" +description = "Scripts to fetch Ada Quality and Style Guide wikibook " +version = "0.1.0-dev" + +authors = ["Max Reznik"] +maintainers = ["Max Reznik "] +maintainers-logins = ["reznikmm"] + +executables = ["aqs2mdx"] +project-files = ["gnat/aqs2mdx.gpr"] + +configuration.output_dir = "gnat" +configuration.generate_ada = false +configuration.generate_c = false + +[[depends-on]] +matreshka_league = "*" diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 0000000..b2383ed --- /dev/null +++ b/data/.gitignore @@ -0,0 +1 @@ +*.wiki \ No newline at end of file diff --git a/fetch.sh b/fetch.sh new file mode 100755 index 0000000..7ff4124 --- /dev/null +++ b/fetch.sh @@ -0,0 +1,50 @@ +#!/bin/bash +set -e + +OUTPUT=${1:-/tmp/src/ada-lang-io/docs/style-guide} +AQS2MDX=./bin/aqs2mdx + +mkdir -p $OUTPUT + +curl -o data/Ada_Style_Guide.wiki "https://en.wikibooks.org/w/index.php?title=Ada_Style_Guide&action=raw" + +CHAPTERS=`grep -F '* [[' data/Ada_Style_Guide.wiki | sed -e 's#.*/\([^|]*\)|.*#\1#' -e 's/ /_/g'` +INDEX=2 +for J in $CHAPTERS; do + curl -o data/$J.wiki "https://en.wikibooks.org/w/index.php?title=Ada_Style_Guide/$J&action=raw" + # Suppress quote format to replace it latter + # Fix definition lists to help pandoc understand them + sed -e 's/^:/QUOTE/' -e '/^;/s/:/\n:/' -e 's//\\/' data/$J.wiki | + pandoc -f mediawiki -t gfm --filter $AQS2MDX > /tmp/mdx + # Use quote markdown + sed -i -e 's/^QUOTE/>/' /tmp/mdx + # Create front matter + cat > /tmp/front_matter <<-EOF +--- +title: ${J//_/ } +sidebar_position: $INDEX +--- + +EOF + cat /tmp/front_matter /tmp/mdx > $OUTPUT/$J.mdx + INDEX=$((INDEX+1)) +done + +# Create front matter for the index page +cat > /tmp/front_matter <<-EOF +--- +title: Ada Quality and Style Guide +description: Guidelines for Professional Programmers +sidebar_position: 1 +draft: true +slug: /style-guide +--- + +> __*Guidelines for Professional Programmers*__ + +EOF + +sed -e '//,/<.noinclude>/d' data/Ada_Style_Guide.wiki | + pandoc -f mediawiki -t gfm --filter ./bin/aqs2mdx > /tmp/mdx + +cat /tmp/front_matter /tmp/mdx > $OUTPUT/Ada_Style_Guide.mdx diff --git a/gnat/aqs2mdx.gpr b/gnat/aqs2mdx.gpr new file mode 100644 index 0000000..d9e701f --- /dev/null +++ b/gnat/aqs2mdx.gpr @@ -0,0 +1,18 @@ +with "import_style_guide_config.gpr"; +project Aqs2mdx is + + for Source_Dirs use ("../source/"); + for Object_Dir use "../obj/" & import_style_guide_config.Build_Profile; + for Create_Missing_Dirs use "True"; + for Exec_Dir use "../bin"; + for Main use ("aqs2mdx.adb"); + + package Compiler is + for Default_Switches ("Ada") use import_style_guide_config.Ada_Compiler_Switches; + end Compiler; + + package Binder is + for Switches ("Ada") use ("-Es", "-W8"); -- Symbolic traceback + end Binder; + +end Aqs2mdx; diff --git a/gnat/import_style_guide_config.gpr b/gnat/import_style_guide_config.gpr new file mode 100644 index 0000000..78639e6 --- /dev/null +++ b/gnat/import_style_guide_config.gpr @@ -0,0 +1,49 @@ +-- Configuration for import_style_guide generated by Alire +with "matreshka_league.gpr"; +abstract project Import_Style_Guide_Config is + Crate_Version := "0.1.0-dev"; + Crate_Name := "import_style_guide"; + + Alire_Host_OS := "linux"; + + Alire_Host_Arch := "x86_64"; + + Alire_Host_Distro := "ubuntu"; + Ada_Compiler_Switches := External_As_List ("ADAFLAGS", " ") & + ( + "-Og" -- Optimize for debug + ,"-ffunction-sections" -- Separate ELF section for each function + ,"-fdata-sections" -- Separate ELF section for each variable + ,"-g" -- Generate debug info + ,"-gnatwa" -- Enable all warnings + ,"-gnatw.X" -- Disable warnings for No_Exception_Propagation + ,"-gnatVa" -- All validity checks + ,"-gnaty3" -- Specify indentation level of 3 + ,"-gnatya" -- Check attribute casing + ,"-gnatyA" -- Use of array index numbers in array attributes + ,"-gnatyB" -- Check Boolean operators + ,"-gnatyb" -- Blanks not allowed at statement end + ,"-gnatyc" -- Check comments + ,"-gnaty-d" -- Disable check no DOS line terminators present + ,"-gnatye" -- Check end/exit labels + ,"-gnatyf" -- No form feeds or vertical tabs + ,"-gnatyh" -- No horizontal tabs + ,"-gnatyi" -- Check if-then layout + ,"-gnatyI" -- check mode IN keywords + ,"-gnatyk" -- Check keyword casing + ,"-gnatyl" -- Check layout + ,"-gnatym" -- Check maximum line length + ,"-gnatyn" -- Check casing of entities in Standard + ,"-gnatyO" -- Check that overriding subprograms are explicitly marked as such + ,"-gnatyp" -- Check pragma casing + ,"-gnatyr" -- Check identifier references casing + ,"-gnatyS" -- Check no statements after THEN/ELSE + ,"-gnatyt" -- Check token spacing + ,"-gnatyu" -- Check unnecessary blank lines + ,"-gnatyx" -- Check extra parentheses + ); + + type Build_Profile_Kind is ("release", "validation", "development"); + Build_Profile : Build_Profile_Kind := "development"; + +end Import_Style_Guide_Config; diff --git a/source/aqs2mdx.adb b/source/aqs2mdx.adb new file mode 100644 index 0000000..c5cef2c --- /dev/null +++ b/source/aqs2mdx.adb @@ -0,0 +1,142 @@ +with Ada.Wide_Wide_Text_IO; + +with League.Holders; +with League.JSON.Documents; +with League.JSON.Arrays; +with League.JSON.Objects; +with League.JSON.Values; +with League.Strings; + +procedure Aqs2mdx is + use type League.Strings.Universal_String; + use type League.Holders.Universal_Integer; + + function "+" (T : Wide_Wide_String) return League.Strings.Universal_String + renames League.Strings.To_Universal_String; + + procedure Read_JSON + (Doc : out League.JSON.Documents.JSON_Document); + + function Traverse (Blocks : League.JSON.Arrays.JSON_Array) + return League.JSON.Arrays.JSON_Array; + + function Traverse_Block (Block : League.JSON.Objects.JSON_Object) + return League.JSON.Arrays.JSON_Array; + + --------------- + -- Read_JSON -- + --------------- + + procedure Read_JSON + (Doc : out League.JSON.Documents.JSON_Document) + is + Text : League.Strings.Universal_String; + begin + while not Ada.Wide_Wide_Text_IO.End_Of_File loop + declare + Line : constant Wide_Wide_String := Ada.Wide_Wide_Text_IO.Get_Line; + begin + if not Text.Is_Empty then + Text.Append (Wide_Wide_Character'Val (10)); + end if; + + Text.Append (Line); + end; + end loop; + + Doc := League.JSON.Documents.From_JSON (Text); + end Read_JSON; + + -------------- + -- Traverse -- + -------------- + + function Traverse (Blocks : League.JSON.Arrays.JSON_Array) + return League.JSON.Arrays.JSON_Array + is + List : League.JSON.Arrays.JSON_Array; + begin + for J in 1 .. Blocks.Length loop + declare + Block : constant League.JSON.Objects.JSON_Object := + Blocks (J).To_Object; + Result : constant League.JSON.Arrays.JSON_Array := + Traverse_Block (Block); + begin + for K in 1 .. Result.Length loop + List.Append (Result (K)); + end loop; + end; + end loop; + + return List; + end Traverse; + + -------------------- + -- Traverse_Block -- + -------------------- + + function Traverse_Block (Block : League.JSON.Objects.JSON_Object) + return League.JSON.Arrays.JSON_Array + is + List : League.JSON.Arrays.JSON_Array; + begin + if Block (+"t").To_String.To_Wide_Wide_String = "Table" then + -- Flatting tables because no multiline tables in .md + + declare + Content : constant League.JSON.Arrays.JSON_Array := + Block (+"c").To_Array; + Rows : constant League.JSON.Arrays.JSON_Array := + Content (5).To_Array; + Columns : constant League.JSON.Arrays.JSON_Array := + Rows (1).To_Array; + begin + pragma Assert (Content.Length = 5); + pragma Assert (Rows.Length = 1); + pragma Assert (Columns.Length <= 3); + + for J in 1 .. Columns.Length loop + declare + Item : constant League.JSON.Arrays.JSON_Array := + Columns (J).To_Array; + begin + pragma Assert (Item.Length <= 1); + + for K in 1 .. Item.Length loop + List.Append (Item (K)); + end loop; + end; + end loop; + end; + + elsif Block (+"t").To_String.To_Wide_Wide_String = "Header" + and then Block (+"c").To_Array.Element (1).To_Integer = 2 + and then Block (+"c").To_Array.Element (2) + .To_Array.Element (1).To_String = +"introduction" + then + -- Drop toppest 'Introduction' section header + null; + else + List.Append (Block.To_JSON_Value); + end if; + + return List; + end Traverse_Block; + + Doc : League.JSON.Documents.JSON_Document; + +begin + Read_JSON (Doc); + + declare + Object : League.JSON.Objects.JSON_Object := Doc.To_JSON_Object; + Blocks : League.JSON.Values.JSON_Value := Object (+"blocks"); + begin + Blocks := Traverse (Blocks.To_Array).To_JSON_Value; + Object.Insert (+"blocks", Blocks); + Doc := Object.To_JSON_Document; + end; + + Ada.Wide_Wide_Text_IO.Put_Line (Doc.To_JSON.To_Wide_Wide_String); +end Aqs2mdx;