So what you are looking for is a hybrid ISO with standard Calendar. You are taking the ISO week starting and ending period, but instead of all weeks being exactly 7 days you potentially truncate the 1st and/or last weeks.  
The change to need for this is not actually extensive. For initial query returns the  in the ISO week begin date instead of the 1st of the month. Then the main query then checks for week 1 and if so produces the 1st of the month. The only twist is determining the ISO week begin date. For this I've just included a function I have had for some time specifically for that. The change to the week_days function are marked --<<<.
create or replace function iso_first_of_week(date_in date)
 returns date
 language sql
 immutable strict
 /* 
    Given a date return the 1st day of the week according to ISO-8601. 
    I.e. Return the Date if it is Monday otherwise return the preceding Monday
*/ 
AS $$
   with wk_adj(l_days) as (values  (array[0,1,2,3,4,5,6]))
   select date_in - l_days[ extract (isodow from date_in)::integer ]
     from wk_adj;
$$;
create or replace 
function week_dates( do_date_in date)     
 returns table (week_num integer, first_date date, last_date date)
 language sql 
 immutable strict
as $$
    with recursive date_list(week_num,first_date,terminate_date) as 
         ( select 1
                , iso_first_of_week(do_date_in)::timestamp   --<<<
                , (date_trunc('month', do_date_in) + interval '1 month' - interval '1 day')::timestamp
           union all 
           select week_num+1, (first_date+interval '7 day'), terminate_date
             from date_list
            where first_date+interval '6 day'  < terminate_date::timestamp    
         ) 
    select week_num
         , case when week_num = 1                            --<<<
                then date_trunc('month', do_date_in)::date   --<<<
                else first_date::date                        --<<<
           end                                               --<<<
         , case when (first_date+interval '6 day')::date > terminate_date 
                then terminate_date::date 
                else (first_date+interval '6 day')::date 
           end last_date
    from date_list;
$$; 
---------- Original Reply
You can use a recursive query CTE to get the week number and first date for each week of the month specified. The main query calculates the ending date, shorting the last if necessary.  Then wrap that into a SQL function to return the week number and date range for each week.  See example.
create or replace 
function week_dates( do_date_in date) 
 returns table (ween_num integer, first_date date, last_date date)
 language sql 
 immutable strict
as $$
    with recursive date_list(week_num,first_date,terminate_date) as 
         ( select 1
                , date_trunc('month', do_date_in)::timestamp
                , (date_trunc('month', do_date_in) + interval '1 month' - interval '1 day')::timestamp
           union all 
           select week_num+1, (first_date+interval '7 day'), terminate_date
             from date_list
            where first_date+interval '6 day'  < terminate_date::timestamp    
         ) 
    select week_num
         , first_date::date
         , case when (first_date+interval '6 day')::date > terminate_date 
                then terminate_date::date 
                else (first_date+interval '6 day')::date 
           end last_date
    from date_list;
$$; 
 
Response to: "How can i put the output in a single row with week1, week2, week3, week4 and week5".  This is essentially the initial output that did not satisfy what you wanted. The term for this type action is PIVOT and is generally understood. It stems from transforming row orientation to column orientation. It is not overly difficult but it is messy.
IMHO this is something that belongs in the presentation layer and is not suitable for SQL.  After all you are rearranging the data structure for presentation purposes. Let the database server use its natural format, use the presentation layer to reformat. This allows reuse of the queries instead of rewriting when the presentation is changed or another view of the same data is required.   
If you actually want this then just use your initial query, or see the answer from
@Bohemian. However the below shows how this issue can be handled with just SQL (assuming the function week_dates was created).
select week1s  
     , case when week5e is null 
            then week4e
            else week5e
       end "end of month"
     , week1s  || ' -  ' || week1e  
     , week2s  || ' -  ' || week2e  
     , week3s  || ' -  ' || week3e  
     , week4s  || ' -  ' || week4e  
     , week5s  || ' -  ' || week5e  
  from ( select  max(case when (week_num=1) then first_date else NULL end) as week1s 
              ,  max(case when (week_num=1) then last_date  else NULL end) as week1e         
              ,  max(case when (week_num=2) then first_date else NULL end) as week2s
              ,  max(case when (week_num=2) then last_date  else NULL end) as week2e      
              ,  max(case when (week_num=3) then first_date else NULL end) as week3s
              ,  max(case when (week_num=3) then last_date  else NULL end) as week3e      
              ,  max(case when (week_num=4) then first_date else NULL end) as week4s
              ,  max(case when (week_num=4) then last_date  else NULL end) as week4e      
              ,  max(case when (week_num=5) then first_date else NULL end) as week5s
              ,  max(case when (week_num=5) then last_date  else NULL end) as week5e      
           from week_dates(current_date)
        ) w ; 
As before I have wrapped the above in a SQL function and provide an example here.