diff --git a/members/builtins-proc/src/lib.rs b/members/builtins-proc/src/lib.rs
index b4699cad2f8acc4f7027ea269df9afb8e439f70b..e50cd9fef003bea033dcb15fb4e74f99009200b1 100644
--- a/members/builtins-proc/src/lib.rs
+++ b/members/builtins-proc/src/lib.rs
@@ -10,29 +10,38 @@ pub fn builtin(attr: TokenStream, item: TokenStream) -> TokenStream {
     let attrs = syn::parse_macro_input!(attr as syn::AttributeArgs);
     let syn::ItemFn { vis, decl, block, ident, .. } = &input;
     let syn::FnDecl { ref fn_token, ref inputs, ref output, .. } = **decl;
+    let mut help = None;
+    let mut short_description = None;
 
     let name = syn::Ident::new(&format!("builtin_{}", &ident), input.ident.span());
 
-    let help = attrs
-        .iter()
-        .filter_map(|meta| {
-            if let syn::NestedMeta::Meta(syn::Meta::NameValue(attr)) = meta {
-                if attr.ident == "man" {
-                    if let syn::Lit::Str(help) = &attr.lit {
-                        Some(help.value())
-                    } else {
-                        None
-                    }
+    for attr in attrs {
+        if let syn::NestedMeta::Meta(syn::Meta::NameValue(attr)) = attr {
+            if attr.ident == "man" {
+                if let syn::Lit::Str(h) = &attr.lit {
+                    help = Some(h.value());
                 } else {
-                    None
+                    panic!("`man` attribute should be a string variable");
+                }
+            } else if attr.ident == "desc" {
+                if let syn::Lit::Str(h) = &attr.lit {
+                    short_description = Some(h.value());
+                } else {
+                    panic!("`desc` attribute should be a string variable");
                 }
             } else {
-                None
+                panic!("Only the `man` and `desc` attributes are allowed");
             }
-        })
-        .next()
-        .expect("A man page is required! Please add a documentation comment");
-    let man = format!("NAME\n    {} - {}", ident, help.trim());
+        } else {
+            panic!("Only the `man` and `desc` attributes are allowed");
+        }
+    }
+    let help = help.expect("A man page is required! Please add an attribute with name `man`");
+    let help = help.trim();
+    let short_description = short_description
+        .expect("A short description is required! Please add an attribute with name `desc`");
+    let man = format!("NAME\n    {} - {}\n\n{}", ident, short_description, help);
+    let help = format!("{}\n\n```txt\n{}\n```", short_description, help);
 
     let result = quote! {
         #[doc = #help]
diff --git a/members/builtins-proc/tests/test.rs b/members/builtins-proc/tests/test.rs
index 09394f13868491938f4cd1bda316d8b49d4d4f93..d04d26c9eb7bd91d8051c7eb1ae6f922a0cb6b27 100644
--- a/members/builtins-proc/tests/test.rs
+++ b/members/builtins-proc/tests/test.rs
@@ -1,13 +1,15 @@
 use ion_shell::{builtins::Status, types, Shell};
 
-/// print 42 to the screen
-///
-/// SYNOPSIS
-///     gimme_the_answer_to_life_to_the_universe_and_to_everything_else [-h | --help]
-///
-/// DESCRIPTION
-///     Who doesn't want 42 printed to screen?
-#[builtins_proc::builtin(man = "a comment")]
+#[builtins_proc::builtin(
+    desc = "prints 42 to the screen",
+    man = "
+SYNOPSIS
+    gimme_the_answer_to_life_to_the_universe_and_to_everything_else [-h | --help]
+
+DESCRIPTION
+    Who doesn't want 42 printed to screen?
+"
+)]
 fn gimme_the_answer_to_life_to_the_universe_and_to_everything_else(
     args: &[types::Str],
     _shell: &mut Shell<'_>,
diff --git a/src/lib/builtins/mod.rs b/src/lib/builtins/mod.rs
index d83b4cf1d1cb139271ef8356a8120391da23972b..f94703d54a8a5622d4808bf15811af5430729e9f 100644
--- a/src/lib/builtins/mod.rs
+++ b/src/lib/builtins/mod.rs
@@ -259,16 +259,17 @@ pub fn builtin_dir_depth(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     Status::SUCCESS
 }
 
-#[builtin(man = "
-Change directory.
-
+#[builtin(
+    desc = "Change directory.",
+    man = "
 SYNOPSIS
     cd DIRECTORY
 
 DESCRIPTION
     Without arguments cd changes the working directory to your home directory.
     With arguments cd changes the working directory to the directory you provided.
-")]
+"
+)]
 pub fn cd(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     let err = match args.get(1) {
         Some(dir) => {
@@ -304,15 +305,16 @@ pub fn cd(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     }
 }
 
-#[builtin(man = "
-Returns true if the value given to it is equal to '1' or 'true'.
-
+#[builtin(
+    desc = "Returns true if the value given to it is equal to '1' or 'true'.",
+    man = "
 SYNOPSIS
     bool VALUE
 
 DESCRIPTION
     Returns true if the value given to it is equal to '1' or 'true'.
-")]
+"
+)]
 pub fn bool(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     if args.len() != 2 {
         return Status::error("bool requires one argument");
@@ -332,15 +334,16 @@ pub fn bool(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     Status::SUCCESS
 }
 
-#[builtin(man = "
-prints the directory stack
-
+#[builtin(
+    desc = "prints the directory stack",
+    man = "
 SYNOPSIS
     dirs
 
 DESCRIPTION
     dirs prints the current directory stack.
-")]
+"
+)]
 pub fn dirs(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     // converts pbuf to an absolute path if possible
     fn try_abs_path(pbuf: &PathBuf) -> Cow<'_, str> {
@@ -404,15 +407,16 @@ pub fn dirs(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     }
 }
 
-#[builtin(man = "
-push a directory to the directory stack
-
+#[builtin(
+    desc = "push a directory to the directory stack",
+    man = "
 SYNOPSIS
     pushd DIRECTORY
 
 DESCRIPTION
     pushd pushes a directory to the directory stack.
-")]
+"
+)]
 pub fn pushd(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     enum Action {
         Switch,          // <no arguments>
@@ -480,17 +484,18 @@ pub fn pushd(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     Status::SUCCESS
 }
 
-#[builtin(man = "
-shift through the directory stack
-
+#[builtin(
+    desc = "shift through the directory stack",
+    man = "
 SYNOPSIS
     popd
 
 DESCRIPTION
     popd removes the top directory from the directory stack and changes the working directory to \
-                 the new top directory.
+           the new top directory.
     pushd adds directories to the stack.
-")]
+"
+)]
 pub fn popd(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     let len = shell.dir_stack().dirs().len();
     if len <= 1 {
diff --git a/src/lib/builtins/status.rs b/src/lib/builtins/status.rs
index 6aaec62ebbb80477f1b151010b2737a0d1ca8b1f..51c06c5678ed263618c45c051c5c4a711e81836c 100644
--- a/src/lib/builtins/status.rs
+++ b/src/lib/builtins/status.rs
@@ -4,9 +4,9 @@ use crate::{shell::Shell, types};
 use builtins_proc::builtin;
 use std::env;
 
-#[builtin(man = "
-Evaluates the current runtime status
-
+#[builtin(
+    desc = "Evaluates the current runtime status",
+    man = "
 SYNOPSIS
     status [ -h | --help ] [-l] [-i]
 
@@ -20,7 +20,8 @@ OPTIONS
         returns true if the shell is interactive. Also --is-interactive.
     -f
         prints the filename of the currently running script or else stdio. Also --current-filename.
-")]
+"
+)]
 pub fn status(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
     let mut login_shell = false;
     let mut interactive = false;